2013-09-24 7 views
31

zdałem sobie sprawę, że kiedy piszę do pliku przy użyciu Pythona to czekać aż do końca mojego pliku Pythona, aby go wykonać:Python 2.7: Zapis do pliku natychmiast

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'" 

Jak ja przypuszczam, aby Pythona zapisu natychmiast do pliku wyjściowego?

Odpowiedz

47

Możesz użyć flush() lub możesz ustawić obiekt pliku jako niebuforowany.

Szczegóły na temat używania tego parametru dla open()here.

Więc chcesz zmienić otwarte zaproszenie do -

outputFile = open("./outputFile.txt", "a", 0) 
+2

Dziękuję, druga opcja jest najlepsza dla mnie, ponieważ nie chcę pisać outputFile.flush() za każdym razem, ale obie działają. – elbajo

+1

Zamiast pozostawić plik otwarty podczas operacji czasochłonnych, warto rozważyć instrukcję with, która wykona to samo. – nachshon

+1

@nachshon "wykonaj to samo": nie dla mnie w moim systemie (RHEL 6.8 z [conda] (https://en.wikipedia.org/wiki/Conda_ (package_manager)) na Pythonie 2.7.13). Wywołanie 'os.fsync()' wspomniane w odpowiedzi [ffeast] (https://stackoverflow.com/a/41506739/257924) jest wymagane (nie można powiedzieć na pewno w przypadku Pythona opartego na systemie Microsoft Windows lub innych systemach operacyjnych)). – bgoodr

14

zmusić go z funkcji flush() dodać

outputFile.flush() 

na końcu kodu.

+2

Jeśli kod dodaje się na końcu pliku Pythona, nic nie zostało wykonane, a tak by nie było, gdy plik zostanie zamknięty. Zamiast tego powinno być wykonywane prawdopodobnie wiele razy - zawsze, gdy jest to pożądane, aby upewnić się, że wszystkie dotychczasowe dane wyjściowe zostały zapisane w pliku. – martineau

3

Jak @RyPeck powiedział można użyć flush() lub ustawić obiekt pliku do niebuforowana. jednak zwrócić uwagę na następujące (od https://docs.python.org/2/library/stdtypes.html?highlight=file%20flush#file.flush):

przepłukać bufor wewnętrzny, jak fflush stdio za().

Uwaga flush() niekoniecznie zapisuje dane pliku na dysk. Użyj funkcji flush(), a następnie os.fsync(), aby zapewnić to zachowanie.

I cytat z man 3 fflush:

Należy zauważyć, że fflush() opróżnia jedynie bufory w przestrzeni użytkownika obsługiwane przez bibliotekę C. Aby upewnić się, że dane są fizycznie przechowywane na dysku, należy również przepłukać bufory jądra, na przykład z synchronizacją (2) lub fsync (2).

+0

Call os.fsync() zatrzymuje mój kod od razu –

+0

@Nam 'os.fsync()' działa idealnie na moim systemie (RHEL 6.8 z [conda] (https://en.wikipedia.org/wiki/Conda_ (package_manager)) opartego na języku Python 2.7.13). Jesteś pewien, że nie masz problemów z systemem plików lub przeciążonym systemem? – bgoodr

+0

Nie mam pojęcia. Jestem na Ubuntu Desktop 16 i Pythonie 2.7 –

0

Wystarczy połączyć wszystkie powyższe odpowiedzi na zestaw przydatnych funkcji użytkowych, ponieważ kluczowym wymogiem OP (i ja!) Jest „because I don't want to write outputFile.flush() each time”:

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