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)
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,