proyectos ejemplos python file-io fopen

python - ejemplos - django



Lectura de un archivo actualizado con frecuencia (6)

"Una sesión interactiva vale 1000 palabras"

>>> f1 = open("bla.txt", "wt") >>> f2 = open("bla.txt", "rt") >>> f1.write("bleh") >>> f2.read() '''' >>> f1.flush() >>> f2.read() ''bleh'' >>> f1.write("blargh") >>> f1.flush() >>> f2.read() ''blargh''

En otras palabras, sí, un único "abrir" servirá.

Actualmente estoy escribiendo un programa en python en un sistema Linux. El objetivo es leer un archivo de registro y ejecutar un comando bash al encontrar una cadena en particular. El archivo de registro está siendo escrito constantemente por otro programa. Mi pregunta es:

Si abro el archivo usando el método open () ¿se actualizará mi objeto de archivo de Python a medida que el otro programa escriba en el archivo o tendré que volver a abrir el archivo a intervalos de tiempo?

Gracias

Jim

ACTUALIZACIÓN: Gracias por las respuestas hasta el momento. Tal vez debería haber mencionado que el archivo está siendo escrito por una aplicación Java EE, por lo que no tengo control sobre cuándo se escriben los datos. Actualmente tengo un programa que vuelve a abrir el archivo cada 10 segundos e intenta leer desde la posición de bytes en el archivo que leyó por última vez. Por el momento solo imprime la cadena que se devuelve. Esperaba que el archivo no necesitara ser reabierto, pero el comando de lectura de alguna manera tendría acceso a los datos escritos en el archivo por la aplicación Java.

#!/usr/bin/python import time fileBytePos = 0 while True: inFile = open(''./server.log'',''r'') inFile.seek(fileBytePos) data = inFile.read() print data fileBytePos = inFile.tell() print fileBytePos inFile.close() time.sleep(10)

Gracias por los consejos sobre pyinotify y generadores. Voy a echar un vistazo a estos para encontrar una mejor solución.


Aquí hay una versión ligeramente modificada de la respuesta de que es resistente al truncamiento de archivos. Muy útil si su archivo está siendo procesado por logrotate .

import os import time def follow(name): current = open(name, "r") curino = os.fstat(current.fileno()).st_ino while True: while True: line = current.readline() if not line: break yield line try: if os.stat(name).st_ino != curino: new = open(name, "r") current.close() current = new curino = os.fstat(current.fileno()).st_ino continue except IOError: pass time.sleep(1) if __name__ == ''__main__'': fname = "test.log" for l in follow(fname): print "LINE: {}".format(l)


Dado que tiene como objetivo un sistema Linux, puede usar pyinotify para notificarle cuando cambie el archivo.

También existe this truco, que puede funcionar bien para ti. Utiliza file.seek para hacer lo que tail -f hace.


No soy un experto aquí, pero creo que tendrá que usar algún tipo de patrón de observador para mirar pasivamente el archivo y luego disparar un evento que vuelva a abrir el archivo cuando se produzca un cambio. En cuanto a cómo realmente implementar esto, no tengo idea.

No creo que open () abra el archivo en tiempo real como sugieres.


Si tiene el código leyendo el archivo ejecutándose en un ciclo while:

f = open(''/tmp/workfile'', ''r'') while(1): line = f.readline() if line.find("ONE") != -1: print "Got it"

y está escribiendo en ese mismo archivo (en modo de adición) desde otro programa. Tan pronto como se anexe "ONE" en el archivo, obtendrá la impresión. Puedes tomar cualquier acción que quieras tomar. En resumen, no tiene que volver a abrir el archivo a intervalos regulares.

>>> f = open(''/tmp/workfile'', ''a'') >>> f.write("One/n") >>> f.close() >>> f = open(''/tmp/workfile'', ''a'') >>> f.write("ONE/n") >>> f.close()


Yo recomendaría mirar los Trucos de Generador de David Beazley para Python , especialmente la Parte 5: Procesamiento de datos infinitos . Controlará el equivalente de Python de un comando de tail -f logfile en tiempo real.

# follow.py # # Follow a file like tail -f. import time def follow(thefile): thefile.seek(0,2) while True: line = thefile.readline() if not line: time.sleep(0.1) continue yield line if __name__ == ''__main__'': logfile = open("run/foo/access-log","r") loglines = follow(logfile) for line in loglines: print line,