2013-09-24 67 views
31

我意識到,當我使用Python編寫成一個文件時,它等待我的Python文件的末尾來執行它:的Python 2.7:寫即時文件

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

我怎麼想,才能使Python寫瞬間到輸出文件?

回答

47

您可以使用flush()或者您可以將文件對象設置爲無緩衝。

使用該參數的詳細信息open()here

那麼您會在公開徵集改變 -

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

謝謝,第二個選項對我來說是最好的,因爲我不想每次都寫outputFile.flush(),但兩者都可以工作。 – elbajo

+1

而不是在時間密集型操作中將文件打開,可能值得考慮with語句來完成同樣的事情。 – nachshon

+1

@nachshon「完成相同的事情」:不適合我在我的系統上(RHEL 6.8使用[conda](https://en.wikipedia.org/wiki/Conda_(package_manager)) - 基於Python 2.7.13)。在[ffeast](https://stackoverflow.com/a/41506739/257924)中提到的'os.fsync()'調用是必需的(不能肯定地說明基於Microsoft Windows的Python或其他操作系統的)。 – bgoodr

14

flush()功能強迫它,在你的代碼的末尾添加

outputFile.flush() 

+2

如果代碼是在加Python文件的結尾,沒有任何東西是完成的,當文件關閉時不會發生。相反,它應該被執行多次 - 每當需要確保所有輸出到目前爲止寫入文件。 – martineau

3

正如@RyPeck說,你可以使用flush()或設置文件對象是 緩衝。 但要注意以下(從 https://docs.python.org/2/library/stdtypes.html?highlight=file%20flush#file.flush):

刷新內部緩存,像標準輸入輸出的fflush()。

注意flush()不一定將文件的數據寫入磁盤。使用flush()後跟os.fsync()來確保這種行爲。

而且從man 3 fflush報價:)

注意fflush(僅僅刷新由C庫提供的用戶空間緩衝區。爲確保數據在物理上存儲在磁盤上,內核緩衝區也必須被刷新,例如,帶有同步(2)或fsync(2)的 。

+0

調用os.fsync()立即停止我的代碼 –

+0

@Nam'os.fsync()在我的系統上完美工作(RHEL 6.8 with [conda](https://en.wikipedia.org/wiki/Conda_(package_manager )) - 基於Python 2.7.13)。你確定你沒有文件系統問題或系統過載嗎? – bgoodr

+0

我不知道。我在Ubuntu桌面16和Python 2.7上 –

0

就上述所有的答案組合成一套有用的實用功能,因爲OP的一個關鍵要求(和我!)是「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")