close()在Python中是否意味着flush()?

close()在Python中是否意味着flush()?,python,operating-system,flush,Python,Operating System,Flush,在Python中,通常-对文件对象执行close()操作是否意味着执行flush()操作?是。它使用底层的close()函数,该函数为您()执行此操作。NB:close()和flush()不会确保磁盘上的数据实际上是安全的。它只是确保操作系统具有数据==并且该数据未在进程内缓冲 您可以尝试同步或fsync将数据写入磁盘。filehandle.close不一定刷新。令人惊讶的是,filehandle.flush也帮不上忙——当Python运行时,它仍然会卡在操作系统缓冲区中。观察本次会话,其中我写

在Python中,通常-对文件对象执行
close()
操作是否意味着执行
flush()
操作?

是。它使用底层的
close()
函数,该函数为您()执行此操作。

NB:
close()
flush()
不会确保磁盘上的数据实际上是安全的。它只是确保操作系统具有数据==并且该数据未在进程内缓冲


您可以尝试同步或fsync将数据写入磁盘。

filehandle.close不一定刷新。令人惊讶的是,filehandle.flush也帮不上忙——当Python运行时,它仍然会卡在操作系统缓冲区中。观察本次会话,其中我写入了一个文件,将其关闭,并在shell命令提示符下按Ctrl-Z键,然后检查了该文件:

$  cat xyz
ghi
$ fg
python

>>> x=open("xyz","a")
>>> x.write("morestuff\n")
>>> x.write("morestuff\n")
>>> x.write("morestuff\n")
>>> x.flush
<built-in method flush of file object at 0x7f58e0044660>
>>> x.close
<built-in method close of file object at 0x7f58e0044660>
>>> 
[1]+  Stopped                 python
$ cat xyz
ghi
$cat xyz
ghi
$fg
python
>>>x=打开(“xyz”,“a”)
>>>x.write(“morestuff\n”)
>>>x.write(“morestuff\n”)
>>>x.write(“morestuff\n”)
>>>同花顺
>>>关闭
>>> 
[1] +停止python
$cat xyz
ghi

随后,我可以重新打开该文件,这必然会同步该文件(因为在本例中,我是以追加模式打开它的)。正如其他人所说,sync syscall(可从操作系统软件包获得)应该将所有缓冲区刷新到磁盘,但它可能会影响整个系统的性能(它同步系统上的所有文件)。

是的,在Python 3中这是最后一个,但在Python 2中已经是这样了(请参阅)。

作为对这个问题的补充,是的,python会在关闭前刷新,但是如果您想确保数据正确写入磁盘,这是不够的

无论目标文件是否存在,我都会以在UNIX/Linux服务器上自动更新的方式编写文件。请注意,某些文件系统将在关闭+重命名时隐式地将数据提交到磁盘(ext3 with
data=ordered
(默认设置),而ext4在添加写关闭重命名模式的检测和在这些模式上的元数据之前同步数据之前,最初发现了许多应用程序缺陷)

#使用临时名称写入destfile。uxxxxxxxx
base,name=os.path.split(destfile)
tmpname=os.path.join(base,'.{}.'.format(name))#这是tmpfile前缀
将tempfile.NamedTemporaryFile('w',前缀=tmpname,delete=False)作为fd:
#用实际文件路径/名称替换前缀
tmpname=str(fd.name)
尝试:
#在这里写fd。。。前任:
json.dumps({},fd)
#我们希望在关闭前进行fdatasync,因此无论如何,我们都需要在关闭前刷新
fd.flush()
os.fdatasync(fd)
#因为我们使用的是tmpfile,所以还需要设置适当的权限
如果os.path.exists(destfile):
#复制目标文件的掩码
os.fchmod(fd.fileno,os.stat(destfile.st_模式)
其他:
#基于当前umask值设置掩码
umask=os.umask(0o22)
操作系统umask(umask)
os.fchmod(fd.fileno,0o666&~umask)#0o777用于目录和可执行文件)
#现在我们可以关闭并重命名该文件(覆盖任何现有文件)
fd.close()
重命名(tmpname,destfile)
除:
#出现错误时,请尝试清理临时文件
尝试:
操作系统取消链接(tmpname)
除操作错误外:
通过
提升
我想如果Python提供了简单的方法来解决这个问题会很好。。。同时,我想如果您关心数据的一致性,那么最好在较低的级别上真正了解正在发生的事情,特别是因为不同的操作系统和文件系统之间存在许多差异


还要注意的是,这并不保证写入的数据可以恢复,只保证您将获得数据的一致副本(旧的或新的)。为了确保在返回时安全地写入和访问新数据,您需要在重命名后使用
os.fsync(…)
,即使在写入路径中有不安全的缓存,也可能丢失数据。这在消费级硬件上很常见,尽管任何系统都可以配置为不安全写入,这也会提高性能。至少,即使使用不安全的缓存,上述方法仍应保证您获得的数据的任何副本都是有效的

(换句话说:缓冲的文件I/O是大的抽象文件,隐藏在你面前。执行
打开
写入
关闭
,不应该让东西不写,因为这是你用
写入
已经准备好的。一个缓冲区,通常会吃掉扔进它的东西,这将是一个非常糟糕的设计[或者是一个饥饿的缓冲区])谢谢,这也是我的猜测。但这是真正的跨平台、跨操作系统和跨语言吗?@Adam Matan:这就是为什么Python位于C库之上。为了确保“真正的跨平台、跨操作系统”。我不知道“跨语言”是什么意思。+1谢谢。通过“跨语言”我想问的是,在绝大多数现代编程语言中,这种行为是否相似。“是的,它使用底层的close()函数来为您实现这一点……”->我认为您应该阅读
man2close()
再次强调,因为这不是真的。是真的,但现代操作系统在进程终止时是否会将数据写入磁盘?取决于您所说的时间尺度。例如,某些版本的ext4可能会等待整秒才将数据提交到磁盘。+1如果数量级是秒,我就很安全了。谢谢!嗯-我怀疑您的专业人士问题是,您实际上没有调用
flush()
close()
——您只是显示了它们的表示形式!您需要paren来调用这些方法。