是否可以检查文件是否已在python中删除或重新创建?
例如,如果您在脚本中执行了open("file")
,然后在该文件仍处于打开状态时执行rm file; touch file;
,则脚本仍会保留对旧文件的引用,即使它已被删除。
答案 0 :(得分: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
好的,这个文件有一个链接,所以文件系统中有一个名字。现在删除它:
>>> os.unlink("testdv.py")
>>> os.fstat(f.fileno()).st_nlink
0
没有更多链接,所以我们有一个只有kept alive as long as we have it open的“匿名文件”。创建具有相同名称的新文件对旧文件没有影响:
>>> g = open("testdv.py", "w")
>>> os.fstat(g.fileno()).st_nlink
1
>>> os.fstat(f.fileno()).st_nlink
0
当然,st_nlink
有时最初可能是>1
,因此检查零是不完全可靠的(尽管在受控设置中,它可能已经足够好了)。相反,您可以通过比较stat
结果来验证最初打开的路径中的文件是否与您具有文件描述符的文件相同:
>>> os.stat("testdv.py") == os.fstat(f.fileno())
False
>>> os.stat("testdv.py") == os.fstat(g.fileno())
True
(如果您希望这100%正确,那么您应该仅比较st_dev
个结果中的st_ino
和stat
字段,因为其他字段和{{1}特别是在调用之间可能会发生变化。)
答案 1 :(得分:4)
是。使用the os.stat()
function检查文件长度。如果长度为零(或函数返回错误“File not found”),则有人删除了该文件。
或者,您可以在每次需要写入文件时打开+写入+关闭文件。缺点是打开文件是一个非常慢的操作,所以如果你需要编写大量数据,这是不可能的。
为什么呢?因为新文件不是您打开的文件。简而言之,Unix文件系统有两个级别。一个是目录条目(即文件名,文件大小,修改时间,指向数据的指针),第二个级别是文件数据。
当您打开文件时,Unix使用该名称来查找文件数据。之后,它仅在第二级运行 - 对目录条目的更改对任何打开的“文件句柄”都没有影响。这正是您删除目录条目的原因:您的程序没有使用它。
使用os.stat()
时,不会再查看文件数据,而是再次查看目录条目。
从积极的方面来说,这允许您创建除了您的程序之外无人能看到的文件:打开文件,删除它然后使用它。由于该文件没有目录条目,因此没有其他程序可以访问该数据。
从消极方面来说,你无法轻易解决像你所拥有的问题。
答案 2 :(得分:3)
是 - 您可以使用inotify
工具检查文件更改等。还有一个Python binding。使用inotify,您可以查看文件系统活动的文件或目录。从手册中可以检测到以下事件:
IN_ACCESS File was accessed (read) (*).
IN_ATTRIB Metadata changed, e.g., permissions, timestamps, extended attributes, link count (since Linux 2.6.25), UID, GID, etc. (*).
IN_CLOSE_WRITE File opened for writing was closed (*).
IN_CLOSE_NOWRITE File not opened for writing was closed (*).
IN_CREATE File/directory created in watched directory (*).
IN_DELETE File/directory deleted from watched directory (*).
IN_DELETE_SELF Watched file/directory was itself deleted.
IN_MODIFY File was modified (*).
IN_MOVE_SELF Watched file/directory was itself moved.
IN_MOVED_FROM File moved out of watched directory (*).
IN_MOVED_TO File moved into watched directory (*).
IN_OPEN File was opened (*).
从这里你可以谷歌自己一个解决方案,但我认为你得到了整体的想法。当然,这可能仅适用于Linux,但是根据您的问题我假设您正在使用它(对rm
和touch
的引用)。