2013-09-24 35 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")