【问题标题】:Seeing multiple events with Python watchdog library when folders are created创建文件夹时使用 Python 看门狗库查看多个事件
【发布时间】:2017-09-22 19:34:54
【问题描述】:

我遇到了一些问题,我看到了我没有预料到的其他事件。

我正在查看文件夹C:\Users\kvasko\Downloads\data。如果我复制一个文件夹2017\07\25\LogFile.xml,我将看到以下 3 个“已创建”事件,而我预计只会看到 1 个。如果我提前创建日期文件夹结构(但在应用程序运行时监视文件夹),它将只像我期望的那样生成一个事件。我从来没有收到仅创建文件夹的事件。就像正在为创建文件夹生成事件一样,但是在检查我的on_created(self,event) 上发送的实际事件时,所有三个外观事件看起来都完全相同。这是怎么回事?

这是示例输出和最小示例。

2017-09-22 13:58:10,182 - root - INFO - Watchdog: file created C:\Users\kvasko\Downloads\data\2017\07\25\LogFile.xml
2017-09-22 13:58:11,184 - root - INFO - Watchdog: file created C:\Users\kvasko\Downloads\data\2017\07\25\LogFile.xml
2017-09-22 13:58:12,187 - root - INFO - Watchdog: file created C:\Users\kvasko\Downloads\data\2017\07\25\LogFile.xml

我希望:

2017-09-22 13:58:12,187 - root - INFO - Watchdog: file created C:\Users\kvasko\Downloads\data\2017\07\25\LogFile.xml

有没有办法从文件夹创建中检测它是否实际上是多个事件?

以下是我的观察者配置。

folder = "C:\\Users\\kvasko\\Downloads\\data"
observer = Observer(MyProcessHandler(patterns=["*.xml"]), folder, recursive=True)
observer.start_observer()

os.mkdirs("C:\\Users\\kvasko\\Downloads\\data\\2017\\07\\25")
shutil.copy2("C:\temp\LogFile.xml", "C:\\Users\\kvasko\\Downloads\\data\\2017\\07\\25")

try:
    while True:
        time.sleep(5)
except:
    print("Error")

以下是我的处理程序类。

import logging
from watchdog.events import PatternMatchingEventHandler

class MyProcessHandler(PatternMatchingEventHandler):

def on_created(self, event):
    logging.info("Watchdog: file created " + str(event.src_path))

编辑:

这是一个最小的工作示例:

import time
import os
import shutil
import datetime
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler

class   TestEventHandler(PatternMatchingEventHandler):
    def on_created(self, event):
        print (str(datetime.datetime.now()) + " " + str(event))

if __name__ == '__main__':
    path = "C:\\Temp"
    event_handler = TestEventHandler(patterns=["*.xml"])
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    os.makedirs("C:\\Temp\\2017\\07\\25")
    shutil.copy2("C:\\Temp2\\2017\\07\\25\\test.xml", "C:\\Temp\\2017\\07\\25")

    try:
       while True:
           time.sleep(1)
    except KeyboardInterrupt:
       observer.stop()
    observer.join()

打印出来:

2017-09-22 15:49:51.334262 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>
2017-09-22 15:49:52.335468 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>
2017-09-22 15:49:53.340998 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>

编辑2:

将 on_created() 更改为 on_any_event()。就是这样产生的。

2017-09-23 13:14:57.288792 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>
2017-09-23 13:14:58.291327 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>
2017-09-23 13:14:59.293334 <FileCreatedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>
2017-09-23 13:14:59.293334 <FileModifiedEvent: src_path='C:\\Temp\\2017\\07\\25\\test.xml'>

【问题讨论】:

  • 你的“LogFile.xml”副本是不是多两秒?
  • @LaurentLAPORTE 不,这些文件就像 100KB 一样。
  • @KevinVasko:如果您修改代码以使其成为可运行的示例,这对我们非常有帮助。
  • @KevinVasko 这很奇怪,因为有 3 个事件相隔 1 秒。
  • @unutbu 我编辑了原始问题并添加了 MWE。

标签: python watchdog


【解决方案1】:

您可能遇到this bug。作为一种解决方法,您可以使用 TestEventHandler 类记录最后创建的文件路径,而不响应后续的 on_created 事件 除非路径与上次创建的路径不同,或者该路径已被删除:

import time
import os
import shutil
import datetime
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler

class TestEventHandler(PatternMatchingEventHandler):
    def __init__(self, *args, **kwargs):
        super(TestEventHandler, self).__init__(*args, **kwargs)
        self.last_created = None
    def on_created(self, event):
        path = event.src_path        
        if path != self.last_created:
            print(str(datetime.datetime.now()) + " " + str(event))
            self.last_created = path
    def on_deleted(self, event):
        path = event.src_path
        if path == self.last_created:
            self.last_created = None

if __name__ == '__main__':

    path = "C:\\Temp"
    target_dir = "C:\\Temp\\2017\\07\\25"
    src_dir = "C:\\Temp2\\2017\\07\\25"
    filename = 'test.xml'

    target = os.path.join(target_dir, filename)
    src = os.path.join(src_dir, filename)

    event_handler = TestEventHandler(patterns=["*.xml"])
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    if not os.path.exists(target_dir):
        os.makedirs(target_dir)

    if os.path.exists(target):
        os.unlink(target)

    for i in range(3):
        shutil.copy2(src, target_dir)    

    try:
       while True:
           time.sleep(1)
    except KeyboardInterrupt:
       observer.stop()
    observer.join()

【讨论】:

  • 这似乎是问题所在,您的解决方法非常有效!万分感谢。我将您的解决方案标记为答案。
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多