Seite 1 von 1

mittels pipe eine Virtuelle Datei erstellen???

Verfasst: Donnerstag 6. Januar 2005, 13:22
von jens
Ich möchte zwei Dateien aneinander kleben und diese dann mit einem anderen Programm weiter verarbeiten...

Kann ich mittles einer Pipe zwei Dateien zu einer virtuellen Datei zusammen bateln, sodas ich mit der Weiterverarbeitung ohne eine TEMP-Datei auskommen kann???

Verfasst: Donnerstag 6. Januar 2005, 13:42
von Dookie
Hi jens,

wenn es in der selben Anwendung ist, warum nicht mit Iteratoren. Im Modul [url=http://www.python.org/doc/current/lib/i ... tions.html]itertools[/b] gibt es dafür recht interessante Funktionen. Mit itertools.chain(*iterables) kannst Du einfach nacheinander über mehrere Dateien zeilenweise iterieren, als währen die aneinander gehängt.
Ansonst kannst Du dir auch einen eigenen Iterator basteln, Beispiele findest du auch in der Doku zu itertools.


Gruß

Dookie

Verfasst: Donnerstag 6. Januar 2005, 14:09
von jens
Nein, die "virtuelle" Datei soll ja von einem anderen Programm aus weiter verarbeitet werden... Das kann ich natürlich auch von meinem Python Skript aus starten...
Ahja, die Dateien sind auch sehr groß so ca. 100MB das Stück...

Verfasst: Donnerstag 6. Januar 2005, 14:22
von Dookie
Aha, dann ist es sinnvoll mit Pipes zu arbeiten, am einfachsten wohl mit popen.


Gruß

Dookie

Verfasst: Donnerstag 6. Januar 2005, 14:35
von jens
Kannst du mir einen ersten Ansatz skizieren??? Ich finde nicht viel Information zu popen() / Pipes...

Verfasst: Donnerstag 6. Januar 2005, 16:31
von Dookie
Ich hab da mal nen Codeschnipsel aus einem meiner Scripts:

Code: Alles auswählen

        os.chdir(os.path.dirname(self.options.fname))
        povray = popen2.Popen4("nice -n10 %s %s" % (povini.POV_EXE,
                                                    self.options.fname),1)
        buf = []
        while povray.poll() == -1:
            povray.fromchild.flush()
            ch = povray.fromchild.read(1)
            if ch not in "\n\r":
                buf.append(ch)
                if len(buf) >= 23 and "".join(buf).startswith("Click"):
                    self.write_status("".join(buf))
            else:
                line = "".join(buf).strip()
                if line:
                    self.write_status(line)
                if "Rendering line" in line:
                    linenrs = re.findall(r'(\d+)\s*of\s*(\d+)', line)[0]
                    percent = float(linenrs[0])/float(linenrs[1])
                    statusbar.set_progress_percentage(percent)
                buf = []
            while gtk.events_pending():
                gtk.main_iteration_do(False)
        statusbar.set_progress_percentage(0.0)
Hier wird eine Anwendung, im konkreten Fall Povray gestartet und dessen Ausgabe in einer (Gnome-)Statusbar angezeigt.

Umgekehrt vom Script an eine Anwendung etwas schicken ginge natürlich auch, vorausgesetzt die Anwendung kann Daten von stdin verarbeiten. Sonst müsstest Du doch etwas mit Pipes machen, wie das unter Windows geht, hab ich leider keine Ahnung. Unter Linux kann man Pipes wie normale Dateien öffnen, man sollte nur von Zeit zu Zeit ein pipe.flush() machen, damit der interne Puffer auch in die Pipe geschrieben wird, sonst bekommt die Anwendung unter Umständen die Daten erst, wenn die Pipe geschlossen wird.


Gruß

Dookie

Verfasst: Donnerstag 6. Januar 2005, 17:21
von jens
Leider geht es über sdtin nicht... :cry:

Verfasst: Donnerstag 6. Januar 2005, 17:35
von Dookie
os.mkfifo könnte das, gibts aber leider nur für unix hmm

Dookie

Verfasst: Freitag 14. Januar 2005, 18:49
von jens
Also wenn ich es mir recht überlege, könnte ich es auch unter Linux anwerden, wenn ich auf die Pipe-Datei per Samba von Windows dran komme???

Also ich pack zwei Dateien mit Python auf dem Linux-Rechner zu einer virtuellen-Pipe-Datei in einem Verz. welches mit Samba freigegeben ist...

Geht das so?

Hast du dafür vielleicht Beispiele???

Mal zur Veranschaulichung:

Code: Alles auswählen

PipeFile = "/tmp/PipeFile.txt"
SourceFile1 = "/daten/file1.txt"
SourceFile2 = "/daten/file2.txt"

os.mkfifo(PipeFile)

s1 = os.open( SourceFile1, "r" )
s2 = os.open( SourceFile2, "r" )

p = os.open( PipeFile, "w+" )

# Geht natürlich nicht so:
p = s1 + s2

Verfasst: Mittwoch 19. Januar 2005, 07:33
von jens
Hat hierfür jemand noch einen Anhaltspunkt für mich? Ich komme nicht weiter... Hab im Netz leider nicht viel Information gefunden... Geht das überhaupt so einfach?

Verfasst: Mittwoch 19. Januar 2005, 12:52
von Dookie
Hi jens,

Code: Alles auswählen

PipeFile = "/tmp/PipeFile.txt"
SourceFile1 = "/daten/file1.txt"
SourceFile2 = "/daten/file2.txt"

os.mkfifo(PipeFile)

s1 = os.open( SourceFile1, "r" )
s2 = os.open( SourceFile2, "r" )

p = os.open( PipeFile, "w+" )

# Geht natürlich so:
for line in s1:
    p.write(line)
s1.close()

for line in s2:
    p.write(line)
s2.close()

p.close()

Gruß

Dookie

Verfasst: Mittwoch 19. Januar 2005, 13:02
von jens
Hmmmm... So einfach geht das???

Aber funktioniert das auch so, als virtuelle Datei???

Gehen wir mal von aus das SourceFile1 und SourceFile2 jeweils 1GB groß sind. Geht das Skript dann nicht hin und schreibt direkt die Daten per Pipe in die Datei PileFile, die somit 2GB Plattenplatz benötigt???

Ich bescheib noch mal das was ich haben möchte:

Die beiden Dateien sollen zu einer virtuellen Datei zusammen gefügt werden, die aber nicht wirklich Plattenplatz belegt. Dennoch kann ich mit einem zweiten Skript diese virtuelle Datei als ganz normale Datei lesen...

Geht das überhaupt?

Verfasst: Mittwoch 19. Januar 2005, 13:45
von Dookie
Hi Jens,

du startest, nach dem erstellen mit mkfifo, die zweite Anwendung, die dann aus der pipe gleich liest, bzw. darauf wartet, daß es Daten aus der pipe bekommt. wenn du dann zeilenweise deine Daten reinschreibst, bekommt diese Anwendung die Daten auch Zeilenweise, bis die pipe wieder geschlossen wird.


Gruß

Dookie

Verfasst: Dienstag 15. Februar 2005, 14:52
von jens
Mal anders gefragt... Wenn ich mit mkfifo eine virtuelle Datei in einem Verzeichniss erstelle, welches per Samba freigegeben ist... Kann dann jedes x-beliebige Windows Programm auf diese Datei zugreifen, als wäre es eine echte???

OK, hab mir jetzt mal was gebastelt:

Code: Alles auswählen

import os

os.mkfifo( "/daten/fifofile.dat" )
f = file(fifoFile, "w")

for i in range( 10 ):
    print i
    f.write( str(i) )
Wenn ich nun die Datei von Windows aus öffne, sehe ich, das das Python Skript die "Daten" schreibt... Es wird bis 10 hochgezählt... Jedoch erhalte ich auf der anderen Seite nur eine leere Datei, wenn ich diese mit Notepad öffne...

EDIT: Also wenn ich auf dem Linux Rechner die Datei öffne, dann ist alles richtig...
Heißt das, man kann es nicht durch Samba sharen???

Verfasst: Dienstag 15. Februar 2005, 15:45
von Leonidas
jens hat geschrieben:Wenn ich nun die Datei von Windows aus öffne, sehe ich, das das Python Skript die "Daten" schreibt... Es wird bis 10 hochgezählt... Jedoch erhalte ich auf der anderen Seite nur eine leere Datei, wenn ich diese mit Notepad öffne...

EDIT: Also wenn ich auf dem Linux Rechner die Datei öffne, dann ist alles richtig...
Heißt das, man kann es nicht durch Samba sharen???
Hast du vielleicht bemerkt, dass man mit ls -l herausbekommt, dass das keine normale Datei sondern ein FIFO ist? Das funktioniert genausowenig wie wenn du versuchen würdest Gerätedateien über Samba freizugeben.

Verfasst: Dienstag 15. Februar 2005, 15:50
von jens
Mir ist schon klar, das es eine FIFO-Datei ist... Schade nur, das man diese nicht über Samba ansprechen kann... Ich dachte das geht...

Gibt es keine Möglichkeit FIFOs unter Windows zu machen?