我在Python 文档的File Objects中找到了这个:
flush()不一定会将文件的数据写入磁盘。使用flush()和os.fsync()来确保此行为。
所以我的问题是:Python到底在flush
做什么?我以为这会强制将数据写入磁盘,但现在我发现并没有。为什么?
我在Python 文档的File Objects中找到了这个:
flush()不一定会将文件的数据写入磁盘。使用flush()和os.fsync()来确保此行为。
所以我的问题是:Python到底在flush
做什么?我以为这会强制将数据写入磁盘,但现在我发现并没有。为什么?
Answers:
通常涉及两个级别的缓冲:
内部缓冲区是由您针对其进行编程的运行时/库/语言创建的缓冲区,其目的是通过避免每次写入都调用系统来加快处理速度。取而代之的是,当您写入文件对象时,您将写入其缓冲区,并且只要缓冲区被填满,就会使用系统调用将数据写入实际文件。
但是,由于操作系统缓冲区的原因,这可能并不意味着数据已写入disk。这可能仅意味着将数据从运行时维护的缓冲区复制到操作系统维护的缓冲区。
如果您写了一些东西,并且它最终在缓冲区中(仅),并且切断了计算机的电源,则当计算机关闭时,该数据将不在磁盘上。
因此,为了帮助您在各自的对象上使用flush
和fsync
方法。
第一个flush
会简单地将程序缓冲区中残留的所有数据写到实际文件中。通常,这意味着数据将从程序缓冲区复制到操作系统缓冲区。
具体来说,这意味着如果另一个进程打开了要读取的相同文件,它将能够访问刚刷新到该文件的数据。但是,这不一定意味着它已“永久”存储在磁盘上。
为此,您需要调用os.fsync
确保所有操作系统缓冲区与它们所使用的存储设备同步的方法,换句话说,该方法会将数据从操作系统缓冲区复制到磁盘。
通常,您无需为这两种方法烦恼,但是,如果您对磁盘上实际存储的内容抱有偏执是好事,则应按照说明进行两次调用。
2018年补遗。
请注意,具有缓存机制的磁盘现在比2013年更加普遍,因此现在涉及的缓存和缓冲区级别更高。我认为这些缓冲区也将由sync / flush调用处理,但我真的不知道。
fsync
是原子性所必需的。您不能期望关闭文件,重新打开文件并找到fsync
中间没有中间内容的内容。它通常可以工作,但是在带有ext4和默认挂载选项的linux上不起作用。也fsync
不能保证真正使磁铁翻转到盘子上,因为:1:可以禁用fsync(通过笔记本电脑模式); 2:可能不指示硬盘内部缓冲冲洗。
因为操作系统可能不会这样做。刷新操作将文件数据强制进入RAM中的文件缓存,然后从那里开始,操作系统的工作就是将其实际发送到磁盘。
actually
在这里是相对的:如果目标设备已启用写缓存,则返回时数据可能未到达实际的磁盘/芯片os.fsync()
。
它刷新内部缓冲区,这应该导致操作系统将缓冲区写出到文件中。[1] 除非您另行配置,否则Python使用操作系统的默认缓冲。
但是有时OS仍然选择不合作。尤其是在Windows / NTFS中具有诸如写入延迟之类的奇妙功能。基本上清除了内部缓冲区,但OS缓冲区仍保持不变。因此,os.fsync()
在这种情况下,您必须告诉操作系统将其写入磁盘。
with file('blah') as fd: #dostuff
构造时,我知道它保证关闭文件描述符。它也刷新或同步吗?