while line = file.readline(): (geht net, wiso!?)

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.
Antworten
mirko_steiner
User
Beiträge: 4
Registriert: Sonntag 17. Juli 2005, 13:18

hi,

erstmal mein code hier:

Code: Alles auswählen

#!/usr/bin/env python

from select import *
import sys

print "opening fifo"
file = open("test.fifo")

print "poll create"
polly	= poll()
print "poll register"
polly.register(file.fileno(),POLLIN)

while True:
	polly.poll()

	while line = file.readline():
		print line,
ich verstehe nicht wiso das nicht geht, also ich meine ist "line = file.readline()" nicht ein gültiger ausdruck?

kenne das von C z.B.

Code: Alles auswählen

while (c = getchar())
vielleicht kapier ich auch irgendwas nicht ;)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mirko_steiner hat geschrieben: ich verstehe nicht wiso das nicht geht, also ich meine ist "line = file.readline()" nicht ein gültiger ausdruck?
Hi!

1.
file ist ein reservierter Name und steht für open. Verwende einen anderen Variablenamen.

2.
Diese Anweisung läuft jede Zeile durch und bricht nicht bei einer leeren Zeile ab:

Code: Alles auswählen

f = open("test.fifo")
for line in f:
    print line,
Ob das allerdings auch bei FIFO-Dateien funktioniert kann ich dir, mangels Erfahrung damit, nicht sagen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mirko_steiner
User
Beiträge: 4
Registriert: Sonntag 17. Juli 2005, 13:18

ja das problem mit

Code: Alles auswählen

for line in file
ist das das ein EOF erwartet und das kommt halt bei einer FIFO net :)

es müsste so laufen:
sobald sich was ändert an der date (deswegen der poll) lese alle zeilen die drinne stehen und dann warte wieder bis irgendwas passiert.
aber readlines() kann ich auhc nicht benutzten, da das wieder ein EOF erwartet ;)

Code: Alles auswählen

while zeile = datei.readline():
    print zeile,
währe ideal wenn es gehen würde!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mirko_steiner hat geschrieben: ist das das ein EOF erwartet und das kommt halt bei einer FIFO net :)
Hi!

Vielleicht bringt dich dieser Link weiter. Wenn du herausgefunden hast, wie es richtig funktioniert, wäre es super, wenn du uns die richtige Lösung hier im Forum postest. :)

http://nixdoc.net/files/forum/about49896.html

mfg
Gerold
:-)
Zuletzt geändert von gerold am Montag 18. Juli 2005, 08:43, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi

noch eine kleine Bemerkung:
Das '=' ist eine Zuweisung und kein Vergleich. Vielleicht hilft es einfach Klammern zu setzten? Z. B.

Code: Alles auswählen

while (line = fname.readline()):
Das wuerde eher C entsprechen, oder?
Ansonsten musst Du das eben ueber ein paar Zeilen verteilen ...

Gruss,
Christian

PS Habe gerade keinen Zugang zu einem Rechner mit Python drauf, das oben ist also bloss geraten ...
mirko_steiner
User
Beiträge: 4
Registriert: Sonntag 17. Juli 2005, 13:18

nein, mit klammern hab ich schon experimentiert (hab alle arten dorsch!) :) aber ich schau mir mal auf der arbeit (wo ich ja auch eigentlich das problem lösen sollte) die seite genauer an und versuch mal ein paar sachen, aufjedenfall greifen die nicht mit den normalen "file object" methoden drauf zu...
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mirko_steiner hat geschrieben: aufjedenfall greifen die nicht mit den normalen "file object" methoden drauf zu...
Hi!
Im letzten Beispiel schon :wink:

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Gast

also generell zu fifos:

eine fifo muss auf beiden enden (input/output) attached sein damit sie richtig funktioniert. Sonst macht man z.B. ein

Code: Alles auswählen

echo "blahfasel" > fifo
und das teil "hängt".

wenn man in python die datei öffnet

Code: Alles auswählen

datei.open("fifo")
schläft das python script solange (wenn nichts reinkommt) bis etwas reinkomt und legt dan los.
problem hierbei ist wenn man macht:

Code: Alles auswählen

while True:
    datei.open("fifo")
    print datei.readline()
    datei.close()
arbeitet es erstmal "sinnig" also öffnen - zeile lesen - schliesen - wieder öffnen (und damit schlafen bis was passiert). ALLERDINGS verliert man unter umständen zeilen wenn in die fifo mehrere zeilen reingeschrieben werden (in meinem fall lasse ich syslog reinschreiben und wenn jemand hier mist baut dann können schon 15.000 zeilen in 10min zustande kommen (4.16 zeilen pro sekunde wenn ich mich nicht verrechnet habe)).

wenn man das mit open und close weglässt, und nur readline() macht, und man den prozess beendeet der reinschreibt, dann geht die load hoch weil er ohne ende versucht "readline" zu machen (also der prozess nimmt sich ressourcen was geht).

hier ist die lösung die bis jetzt (ich habe es schon getestet und läuft cool) am besten funktioniert hatt:

erstmal der "writer":

Code: Alles auswählen

#! /usr/bin/env python

import sys
from time import *

fifo = open("test", "a") # Mode "a" or "w"

while True:
    try:
        print "writing one line"
        fifo.write("single line.\n")
        fifo.flush()
        sleep(5)

    except IOError:
        break

    try:
        print "writing two line"
        fifo.write("first line.\nsecond one\n")
        fifo.flush()
        sleep(5)

    except IOError:
        break
dann der listener:

Code: Alles auswählen

#! /usr/bin/env python

import sys

while True:
    print "open"
    fifo = open("test","r")

    c = 0
    while True:
        line = fifo.readline()
        c += 1
        print c
        if line:
            print line,
        else:
            print "close"
            fifo.close()
            print "re-open"
            fifo = open("test","r")
zum testen halt beides starten (erst den writer, dann den listener) davor allerdings nicht vergessen die fifo datei zu erstellen mit mkfifo.
Dann den writer beenden (STRG+C) und der listener hört auf zu lesen, closed, open und wartet :)

bei fragen - mail an mich! :D aber ich hoffe ich habe es ausreichend gut erklärt

PS: funktioniert nachweislich unter FreeBSD und Linux

Edit (Leonidas): Code in Python-Tags gesetzt.
mirko_steiner
User
Beiträge: 4
Registriert: Sonntag 17. Juli 2005, 13:18

letzter eintrag war von mir allerdings hab ich mich vergessen einzuloggen :D
Antworten