mittels pipe eine Virtuelle Datei erstellen???

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 13:22

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???
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 13:42

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
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 14:09

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...
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 14:22

Aha, dann ist es sinnvoll mit Pipes zu arbeiten, am einfachsten wohl mit popen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 14:35

Kannst du mir einen ersten Ansatz skizieren??? Ich finde nicht viel Information zu popen() / Pipes...
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 16:31

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
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 17:21

Leider geht es über sdtin nicht... :cry:
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Donnerstag 6. Januar 2005, 17:35

os.mkfifo könnte das, gibts aber leider nur für unix hmm

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 14. Januar 2005, 18:49

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
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 19. Januar 2005, 07:33

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?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 19. Januar 2005, 12:52

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
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 19. Januar 2005, 13:02

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?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 19. Januar 2005, 13:45

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
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 15. Februar 2005, 14:52

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???
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 15. Februar 2005, 15:45

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten