【问题标题】:Using pyinotify to watch for file creation, but waiting for it to be completely written to disk使用 pyinotify 监视文件创建,但等待它完全写入磁盘
【发布时间】:2011-04-22 00:56:23
【问题描述】:

我正在使用 pyinotify 来监视文件夹以了解何时在其中创建文件。当创建某些文件时,我想移动它们。问题是,一旦文件被创建(显然),我的程序就会尝试移动它,甚至在它完全写入磁盘之前。

有没有办法让 pyinotify 等到文件完全写入磁盘后才通知我它已创建?或者有什么简单的方法,在我收到通知后,让 python 等待移动它,直到它写完?

【问题讨论】:

    标签: python linux file pyinotify


    【解决方案1】:

    让 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 (*)
    

    【讨论】:

    • 请注意,这将捕获修改以及创建(如果您正在镜像可能是所需行为的目录)。如果您只想在检测到 new 文件时触发,您将需要一个自定义处理程序来跟踪 IN_CREATE 事件,然后等待它们完成(也通过观察 IN_CLOSE_WRITE 事件)。
    • 如何获取文件名?
    • @NPE:使用process_IN_CLOSE_WRITE 方法将MyProcessEvent 定义为pyinotify.ProcessEvent 的子类。当发生 CLOSE_WRITE 事件时,将使用参数 event 调用 process_IN_CLOSE_WRITEevent.pathname 是已关闭文件的路径。见this, for example
    • @unutbu 很好的解释,如何获取文件名?
    • @NPE:你可以使用os.path.basename(event.pathname)
    【解决方案2】:

    在这个级别上很难判断是否正在写入文件。您可以做的是测试文件是否被其他进程打开。

    1) 从打开文件时使用的各种标志来看,O_EXLOCK 标志可能会有所帮助。 如果设置了 O_EXLOCK 标志,则文件描述符对文件具有排他锁。 所以我的理解是如果你可以用 O_EXLOCK 标志做 os.open() ,它不会被其他进程打开。 这应该适用于所有与 posix 兼容的操作系统,但我尚未对其进行测试。如果文件已打开,则您可以关闭,等待并重试。

    2) 您还可以尝试 os.stat 并查看更改的时间戳并尝试安全地解释信息。虽然这不是万无一失的。

    3) 在 unix 系统上,你可以试试 "lsof"

    4) 以下页面描述了使用 /proc/PID/fd 中的符号链接来测试打开的文件

    [编辑:链接已更新]

    【讨论】:

      【解决方案3】:

      如果您可以控制写入过程,则可以在写入文件时调用文件“foo.part”,并在关闭时将其重命名为“foo”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-14
        • 2019-01-03
        • 1970-01-01
        相关资源
        最近更新 更多