检查在python中打开后是否删除了打开的文件

use*_*906 16 python filesystems

是否可以检查文件是否已在python中删除或重新创建?

例如,如果您open("file")在脚本中执行了a ,然后在该文件仍处于打开状态时执行rm file; touch file;,则脚本仍将保留对旧文件的引用,即使它已被删除.

Fre*_*Foo 17

您应该fstat是打开文件的文件描述符.

>>> import os
>>> f = open("testdv.py")
>>> os.fstat(f.fileno())
posix.stat_result(st_mode=33188, st_ino=1508053, st_dev=65027L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=1107, st_atime=1349180541, st_mtime=1349180540, st_ctime=1349180540)
>>> os.fstat(f.fileno()).st_nlink
1
Run Code Online (Sandbox Code Playgroud)

好的,这个文件有一个链接,所以在文件系统中有一个名字.现在删除它:

>>> os.unlink("testdv.py")
>>> os.fstat(f.fileno()).st_nlink
0
Run Code Online (Sandbox Code Playgroud)

没有更多链接,所以我们有一个"匿名文件",只要我们打开它就会保持活着.创建具有相同名称的新文件对旧文件没有影响:

>>> g = open("testdv.py", "w")
>>> os.fstat(g.fileno()).st_nlink
1
>>> os.fstat(f.fileno()).st_nlink
0
Run Code Online (Sandbox Code Playgroud)

当然,st_nlink有时可能>1最初,所以检查零是不完全可靠的(虽然在受控设置中,它可能是足够好的).相反,您可以通过比较stat结果来验证最初打开的路径中的文件是否与您具有文件描述符的文件相同:

>>> os.stat("testdv.py") == os.fstat(f.fileno())
False
>>> os.stat("testdv.py") == os.fstat(g.fileno())
True
Run Code Online (Sandbox Code Playgroud)

(如果你想要100%正确,那么你应该只比较结果上的st_devst_ino字段stat,因为其他字段,st_atime特别是可能在调用之间发生变化.)


Aar*_*lla 5

是的。使用os.stat()函数检查文件长度。如果长度为零(或函数返回错误“找不到文件”),则有人删除了该文件。

或者,您可以在每次需要向其中写入内容时打开+写入+关闭文件。缺点是打开文件是一个非常慢的操作,所以如果你需要写入大量数据,这是不可能的。

为什么?因为新文件不是您打开的文件。简而言之,Unix 文件系统有两个层次。一级是目录项(即文件名、文件大小、修改时间、数据指针),二级是文件数据。

当您打开文件时,Unix 使用名称来查找文件数据。之后,它只在第二级运行——对目录条目的更改对任何打开的“文件句柄”没有影响。这正是您可以删除目录条目的原因:您的程序没有使用它。

使用 时os.stat(),您不会查看文件数据,而是再次查看目录条目。

从积极的方面来说,这允许您创建除了您的程序之外没有人可以看到的文件:打开文件,删除它,然后使用它。由于该文件没有目录条目,因此没有其他程序可以访问该数据。

从消极的方面来说,你不能轻易解决像你遇到的问题。

  • 在 Linux 上,即使文件被删除,您也可以查看 `proc/<pid>/fd/...` 并访问数据。如果您想复制从 youtube 下载的视频,这有时会派上用场;-) (2认同)