【问题标题】:Delete file while another process still writes to it在另一个进程仍在写入文件时删除文件
【发布时间】:2015-03-16 12:56:33
【问题描述】:

我正在尝试使用 Python 写入文件:

import time

fo = open("foo.txt", "a+", 1)

while True:
    fo.write("Some data to write"); 
    time.sleep(.001)

如果我执行此代码,而不仅仅是手动删除“foo.txt”文件,该过程仍会写入某处。

内容会发生什么?进程写入文件,但没有可用的文件。

【问题讨论】:

  • 你在哪个平台上?在 OS X 上,内容会消失。

标签: python file io


【解决方案1】:

来自The Linux Programming Interface Michael Kerrisk

除了维护每个 i-node 的链接计数外,内核还计算文件的打开文件描述(参见第 95 页的图 5-2)。如果一个文件的最后一个链接被删除,并且任何进程都持有引用该文件的打开描述符,那么在所有描述符都关闭之前,该文件实际上不会被删除。

您的脚本已打开该文件,因此它包含一个引用该文件的打开描述符。系统不会在您使用rm 命令删除文件后立即删除它。但它会在你的脚本关闭描述符后删除它。

我在 man 中找到了参考,来自 man remove:

remove() 从文件系统中删除一个名称。它对文件调用 unlink(2),对目录调用 rmdir(2)。

如果删除的名称是文件的最后一个链接,并且没有进程打开该文件,则该文件将被删除,并且它正在使用的空间可供重用。

如果名称是文件的最后一个链接,但任何进程仍然打开该文件,则该文件将一直存在,直到引用它的最后一个文件描述符关闭。

正如@oglu 在他的回答中提到的,这不是可移植的行为。在 Windows 上,您可以选择是否可以删除已打开的文件。

来自CreateFile function at MSDN

FILE_SHARE_DELETE (0x00000004)

启用对文件或设备的后续打开操作以请求删除访问权限。

否则,如果其他进程请求删除访问权限,则无法打开文件或设备。

如果未指定此标志,但已打开文件或设备进行删除访问,则函数失败。

注意删除访问允许删除和重命名操作。

【讨论】:

  • 刚刚测试过了。文件删除没有问题
  • 您能解释一下您是如何测试它的吗? rm 命令将从目录中删除文件,但只要有可能写入或读取文件,linux 内核就会维护 /unnamed/ 文件。还有,从你的脚本。当您的脚本结束时,不再有这种可能性,内核将进行清理
【解决方案2】:

实际的问题是在写入时更改文件描述符会发生什么,这是特定于平台的。

如果您有 POSIX 系统,则 FD 将保持打开状态,直到最后一个使用者关闭它,在这种情况下,无法访问内容(文件已取消链接)。

如果你有windows系统,我认为你不能在文件被写入时删除它(独占访问)。

【讨论】:

  • 问题不在于是否可以访问内容。但是,如果不存在文件,正在写入的内容会发生什么。进程如何写入不存在的文件?
  • 暂时忘记文件。您不是在写入文件,而是在写入文件描述符。只要文件描述符是打开的,你就可以继续写。
  • 另外,作为注释(在 posix 系统中),即使您删除文件(取消链接),该文件仍然存在,直到文件的最后一个 fd 关闭。关闭后,文件消失,存储可以重复使用。换句话说,即使文件名不存在,文件仍然存在,直到该文件的所有 fd 都关闭为止。
猜你喜欢
  • 2013-03-01
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
相关资源
最近更新 更多