【发布时间】:2011-04-22 00:56:23
【问题描述】:
我正在使用 pyinotify 来监视文件夹以了解何时在其中创建文件。当创建某些文件时,我想移动它们。问题是,一旦文件被创建(显然),我的程序就会尝试移动它,甚至在它完全写入磁盘之前。
有没有办法让 pyinotify 等到文件完全写入磁盘后才通知我它已创建?或者有什么简单的方法,在我收到通知后,让 python 等待移动它,直到它写完?
【问题讨论】:
标签: python linux file pyinotify
我正在使用 pyinotify 来监视文件夹以了解何时在其中创建文件。当创建某些文件时,我想移动它们。问题是,一旦文件被创建(显然),我的程序就会尝试移动它,甚至在它完全写入磁盘之前。
有没有办法让 pyinotify 等到文件完全写入磁盘后才通知我它已创建?或者有什么简单的方法,在我收到通知后,让 python 等待移动它,直到它写完?
【问题讨论】:
标签: python linux file pyinotify
让 pyinotify 响应 IN_CLOSE_WRITE 事件:
wm.add_watch(watched_dir, pyinotify.IN_CLOSE_WRITE, proc_fun=MyProcessEvent())
这是来自 man 5 incrontab,但它同样适用于 pyinotify:
IN_ACCESS File was accessed (read) (*)
IN_ATTRIB Metadata changed (permissions, timestamps, extended attributes, 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 (*)
【讨论】:
IN_CREATE 事件,然后等待它们完成(也通过观察 IN_CLOSE_WRITE 事件)。
process_IN_CLOSE_WRITE 方法将MyProcessEvent 定义为pyinotify.ProcessEvent 的子类。当发生 CLOSE_WRITE 事件时,将使用参数 event 调用 process_IN_CLOSE_WRITE。 event.pathname 是已关闭文件的路径。见this, for example。
os.path.basename(event.pathname)。
在这个级别上很难判断是否正在写入文件。您可以做的是测试文件是否被其他进程打开。
1) 从打开文件时使用的各种标志来看,O_EXLOCK 标志可能会有所帮助。 如果设置了 O_EXLOCK 标志,则文件描述符对文件具有排他锁。 所以我的理解是如果你可以用 O_EXLOCK 标志做 os.open() ,它不会被其他进程打开。 这应该适用于所有与 posix 兼容的操作系统,但我尚未对其进行测试。如果文件已打开,则您可以关闭,等待并重试。
2) 您还可以尝试 os.stat 并查看更改的时间戳并尝试安全地解释信息。虽然这不是万无一失的。
3) 在 unix 系统上,你可以试试 "lsof"
4) 以下页面描述了使用 /proc/PID/fd 中的符号链接来测试打开的文件
[编辑:链接已更新]
【讨论】:
如果您可以控制写入过程,则可以在写入文件时调用文件“foo.part”,并在关闭时将其重命名为“foo”。
【讨论】: