Python 2.7: Escribir en un archivo al instante


Me di cuenta de que cuando escribo en un archivo usando python espera hasta el final de mi archivo Python para ejecutarlo:

outputFile = open("./outputFile.txt","a")
outputFile.write("First")
print "Now you have 10sec to see that outputFile.txt is still the same as before"
time.sleep(10)
outputFile.write("Second")
print "Now if you look at outputFile.txt you will see 'First' and 'Second'"

¿Cómo se supone que debo hacer que python escriba instantáneamente en el archivo de salida?

Author: elbajo, 2013-09-24

4 answers

Puede usar flush() o puede configurar el objeto de archivo para que no tenga búfer.

Detalles sobre el uso de ese parámetro para open() aquí.

Así que cambiarías tu llamada abierta a -

outputFile = open("./outputFile.txt", "a", 0)
 57
Author: RyPeck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-24 14:19:22

Forzarlo con la función flush(), añadir

outputFile.flush()

Al final de su código.

 15
Author: ismail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-24 14:17:18

Como @RyPeck dijo, puede usar flush() o establecer el objeto de archivo como sin búfer. Pero tenga en cuenta lo siguiente (de https://docs.python.org/2/library/stdtypes.html?highlight=file%20flush#file.flush):

Limpia el búfer interno, como fflush () de stdio.

Note flush() no necesariamente escribe los datos del archivo en el disco. Utilice flush () seguido de os.fsync () para asegurar este comportamiento.

Y una cita de man 3 fflush:

Tenga en cuenta que fflush() solo vacía los búferes de espacio de usuario proporcionados por la biblioteca C. Para asegurarse de que los datos se almacenan físicamente en el disco, los búferes del núcleo también deben limpiarse, por ejemplo, con sync(2) o fsync(2).

 5
Author: ffeast,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-06 13:25:39

Solo para combinar todas las respuestas anteriores en un conjunto de funciones de utilidad útil porque un requisito clave de la OP (y yo mismo!) es "porque no quiero escribir outputFile.flush() cada vez":

import os
import tempfile
import time


def write_now(filep, msg):
    """Write msg to the file given by filep, forcing the msg to be written to the filesystem immediately (now).

    Without this, if you write to files, and then execute programs
    that should read them, the files will not show up in the program
    on disk.
    """
    filep.write(msg)
    filep.flush()
    # The above call to flush is not enough to write it to disk *now*;
    # according to https://stackoverflow.com/a/41506739/257924 we must
    # also call fsync:
    os.fsync(filep)


def print_now(filep, msg):
    """Call write_now with msg plus a newline."""
    write_now(filep, msg + '\n')


# Example use with the with..as statement:
with tempfile.NamedTemporaryFile(prefix='some_prefix_here.', suffix='.log', dir='.', delete=False) as logf:
    print_now(logf, "this is a test1")
    time.sleep(20)
    print_now(logf, "this is a test2")
 0
Author: bgoodr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-16 15:27:25