【问题标题】:Python (Watchdog) - Waiting for file to be created correctlyPython(看门狗) - 等待文件被正确创建
【发布时间】:2014-03-01 18:10:17
【问题描述】:

我是 Python 新手,我正在尝试实现良好的“文件创建”检测。如果我不放time.sleep(x) 我的文件会以错误的方式详细说明,因为它们仍在文件夹中“创建”。 (缓冲区不为空) 每次创建文件时,如何在不等待x 秒的情况下绕过这个问题?

这是我的代码:

主要:

while 1:
    if len(parser()) > 0: #  arguments are valid
        if len(parser()) == 3:
            log_path = parser()['log_path']
        else:
            log_path = os.getcwd()
        paths = parser()
        if paths:
            handler = Event_Handler()
            observer = Observer()
            observer.schedule(handler, paths['src_fld'], True)
            observer.start()
            try:
                    while True:
                        time.sleep(1)
            except KeyboardInterrupt:
                observer.stop()
            observer.join()
    else:
        exit(1)

Event_Handler 类:

class Event_Handler(FileSystemEventHandler):
    def on_created(self, event):
        if not event.is_directory:
            time.sleep(1)

正如我所说,如果没有 time.sleep(1),如果我尝试处理一个大文件,我会失败,因为它还没有完全写入。

【问题讨论】:

  • 这不是办法。使用这个pyinotify.sourceforge.net
  • Watchdog 是跨平台的,因此更适合。
  • 没有close_written 事件?

标签: python watchdog


【解决方案1】:

为了任何偶然发现这个问题的未来读者,就像我一样,答案似乎是你不能。 Watchdog 不支持也不会支持任何功能来判断文件是否“完整”,因为 Windows 不允许这样做,并且 Watchdog 与系统无关。

如果您使用的是 Linux 或其某个发行版,则 inotify 可能是一个安全的选择。否则,在 Windows 上,我发现的最佳解决方案是:

上传一个大文件 bigfile,然后上传另一个文件 bigfile-complete。当您找到一个文件name-完成时,您返回并上传/传输/反应到原始文件name。在这种情况下,您的文件将全部添加到队列中的受监视目录中 filefile-complete、file2文件2-完成,. . .

轮询文件的大小,直到它在适当的时间内保持固定。如果它没有在足够长的时间内发生变化,您可以合理地确定它已经完成,请像往常一样对其做出反应。

同样,当一个文件被零碎上传到你的目录时,它会生成一个恒定的文件修改的看门狗事件流。您可以轮询这些而不是文件大小,等待它们停止一段合理的时间,然后假设文件已完成并继续。

这些解决方案都不是完美的,但这似乎是 Windows 上 Watchdog 的固有问题。不幸的是,“完美”的解决方案似乎是“切换到 Linux 并使用 inotify”。

【讨论】:

    【解决方案2】:

    尝试在while循环中读取文件:

    def on_created(event):
    
        ...
    
        # WAITING FOR FILE TRANSFER
        file = None
        while file is None:
            try:
                file = open(event.src_path)
            except OSError:
                file = None
                print("WAITING FOR FILE TRANSFER....")
                time.sleep(3)
                continue
    

    【讨论】:

    • 以供将来参考:我在 ubuntu 上使用 Python 3.9.9 和 Watchdog 2.0.2 尝试了此代码,并且 open() 方法在尝试打开文件时不会引发异常,即使它仍然存在复制(我在一个 2GB 的文件上使用了 cp,并在我的日志中看到它在运行此代码时仍在复制)。
    【解决方案3】:

    最简洁的解决方案是使用PatternMatchingEventHandlerpatterns 变量来监控某些类型的文件,而不是使用经过的时间作为指标。

    只需将'.temp' 附加到您正在上传/写入的每个文件中,并在完成后将它们重命名为真实姓名。

    设置patterns 以查找'*.temp' 文件,并使用FileSystemMovedEvent 事件(及其关联的Handler.on_moved() 方法)及其dest_path 值监控它们是否重命名为您想要的任何类型的文件,这将包含文件的新名称,现在已完全写入。

    【讨论】:

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