关于io:python的file.flush()到底在做什么?

what exactly the python's file.flush() is doing?

我在文件对象的python文档中发现了这一点:

flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.

所以我的问题是:python的flush究竟在做什么?我以为它会强制将数据写入磁盘,但现在我发现它不会。为什么?


通常涉及两个级别的缓冲:

  • 内部缓冲区
  • 操作系统缓冲区
  • 内部缓冲区是由正在编程的运行时/库/语言创建的缓冲区,旨在通过避免每次写入时系统调用来加快速度。相反,当您写入一个文件对象时,您将写入它的缓冲区,并且每当缓冲区填满时,数据将使用系统调用写入实际的文件。

    但是,由于操作系统缓冲区的原因,这可能并不意味着数据被写入磁盘。这可能仅仅意味着数据从运行时维护的缓冲区复制到操作系统维护的缓冲区中。

    如果你写了一些东西,而它最终进入了缓冲区(仅限),并且切断了机器的电源,那么当机器关闭时,数据就不在磁盘上。

    因此,为了帮助实现这一点,您可以在各自的对象上使用flushfsync方法。

    第一个,flush,将简单地写出任何在程序缓冲区中停留在实际文件中的数据。通常这意味着数据将从程序缓冲区复制到操作系统缓冲区。

    具体来说,这意味着如果另一个进程打开了同一个文件进行读取,它将能够访问刚刚刷新到该文件中的数据。但是,这并不一定意味着它已经"永久"存储在磁盘上。

    为此,需要调用os.fsync方法,以确保所有操作系统缓冲区与它们所用的存储设备同步,换句话说,该方法将数据从操作系统缓冲区复制到磁盘。

    通常,您不需要为任何一种方法操心,但是如果您处于这样的场景中,对磁盘上实际结束的内容的偏执是一件好事,那么您应该按照指示进行两次调用。

    2018年补遗。

    请注意,具有缓存机制的磁盘现在比2013年更常见,因此现在涉及的缓存和缓冲区级别甚至更多。我假设这些缓冲区也将由sync/flush调用处理,但我不知道。


    因为操作系统可能不会这样做。flush操作强制文件数据进入RAM中的文件缓存,从内存中,操作系统的任务是将数据实际发送到磁盘。


    它刷新内部缓冲区,该缓冲区应该会导致操作系统将缓冲区写入文件中。[1]除非您对其进行了其他配置,否则python将使用操作系统的默认缓冲区。

    但有时操作系统仍然选择不合作。尤其是在windows/ntfs中的写延迟。基本上,内部缓冲区被刷新,但是操作系统缓冲区仍然保留着它。因此,在这种情况下,您必须告诉操作系统使用os.fsync()将其写入磁盘。

    [1]http://docs.python.org/library/stdtypes.html(http://docs.python.org/library/stdtypes.html)


    基本上,flush()会清除RAM缓冲区,它的真正功能是允许您在以后继续向其写入数据,但不应该认为它是最佳/最安全的文件写入功能。它正在刷新您的RAM以获取更多的数据,仅此而已。如果要确保数据安全地写入文件,请改用close()。