zoukankan      html  css  js  c++  java
  • python watchdog监控文件修改

    概述

    watchdog用来监控指定目录/文件的变化,如添加删除文件或目录、修改文件内容、重命名文件或目录等,每种变化都会产生一个事件,且有一个特定的事件类与之对应,然后再通过事件处理类来处理对应的事件,怎么样处理事件完全可以自定义,只需继承事件处理类的基类并重写对应实例方法。

    使用例子

    import sys
    import time
    import logging
    from watchdog.observers import Observer
    from watchdog.events import LoggingEventHandler
    
    if __name__ == "__main__":
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s - %(message)s',
                            datefmt='%Y-%m-%d %H:%M:%S')
        path = sys.argv[1] if len(sys.argv) > 1 else '.'
        event_handler = LoggingEventHandler()
        observer = Observer()
        observer.schedule(event_handler, path, recursive=True)
        observer.start()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()

    使用方法

    • Create an instance of the watchdog.observers.Observer thread class.
    • Implement a subclass of watchdog.events.FileSystemEventHandler (or as in our case, we will use the built-in watchdog.events.LoggingEventHandler, which already does).
    • Schedule monitoring a few paths with the observer instance attaching the event handler.
    • Start the observer thread and wait for it generate events without blocking our main thread.。

    上面两个是events和observer,介绍一下:

    events

    主要的内容都在events这个文件里面
    包含了所有的可监听的事件
    看一下例子的LoggingEventHandler

    class LoggingEventHandler(FileSystemEventHandler):
        """Logs all the events captured."""
    
        def on_moved(self, event):
            super(LoggingEventHandler, self).on_moved(event)
    
            what = 'directory' if event.is_directory else 'file'
            logging.info("Moved %s: from %s to %s", what, event.src_path,
                         event.dest_path)
    
        def on_created(self, event):
            super(LoggingEventHandler, self).on_created(event)
    
            what = 'directory' if event.is_directory else 'file'
            logging.info("Created %s: %s", what, event.src_path)
    
        def on_deleted(self, event):
            super(LoggingEventHandler, self).on_deleted(event)
    
            what = 'directory' if event.is_directory else 'file'
            logging.info("Deleted %s: %s", what, event.src_path)
    
        def on_modified(self, event):
            super(LoggingEventHandler, self).on_modified(event)
    
            what = 'directory' if event.is_directory else 'file'
            logging.info("Modified %s: %s", what, event.src_path)

    watchdog.events.FileSystemEventHandler()
    事件处理器的基类,用于处理事件,用户需继承该类,并在子类中重写对应方法。

    类实例方法如下:

    • self.dispatch(event)
      接收到一个事件后,通过该方法来决定该event由下面哪个方法处理
    • self.on_any_event(event)
      任何事件发生都会首先执行该方法,该方法默认为空,dispatch()方法会先执行该方法,然后再把event分派给其他方法处理

    • self.on_moved(event)
      Called when a file or a directory is moved or renamed,也就是处理DirMovedEvent和FileMovedEvent事件,子类需重写该方法

    • self.on_created(event)
      Called when a file or directory is created,也就是处理DirCreatedEvent和FileCreatedEvent事件,子类需重写该方法

    • self.on_deleted(event)
      Called when a file or directory is deleted,也就是处理DirDeletedEvent和FileDeletedEvent事件,子类需重写该方法

    • self.on_modified(event)
      Called when a file or directory is modified,也就是处理DirModifiedEvent和FileModifiedEvent事件,子类需重写该方法

    observer

    watchdog.observers.Observer(timeout=1)

    该类实现了监控文件变化,触发对应的事件类,然后调用关联的事件处理类来处理事件。该类其实是threading.Thread的子类,通过observer.start()使之运行在一个线程中,不会阻塞主进程运行,然后可以调用observer.stop()来停止该线程
    实例属性及方法:
    observer.schedule(event_handler, path, recursive=False)
    监控指定路径path,该路径触发任何事件都会调用event_handler来处理,如果path是目录,则recursive=True则会递归监控该目录的所有变化。每一次调用schedule()对一个路径进行监控处理就叫做一个watch,schedule()方法会返回这个watch,接着可以对这个watch做其他操作,如为该watch增加多个event处理器等
    注:内部由一个字典handlers来保存所有watch,watch的值是一个集合,包含对应此watch的所有event handler:

    handlers = {
        watch1: set(event_handler1, event_handler2),
        watch2: set(event_handler),
    }
    • observer.add_handler_for_watch(event_handler, watch)
      添加一个新的事件处理器到watch中,watch是ObservedWatch()类或其子类的实例

    • observer.remove_handler_for_watch(event_handler, watch)
      从watch中移除一个事件处理器

    • observer.unschedule(watch)
      移除一个watch及这个watch上的所有事件处理器

    • observer.unschedule_all()
      移除所有watch及关联的事件处理器

    • observer.on_thread_stop()
      等同于observer.unschedule_all()

    • observer.stop()
      调用该方法来停止observer线程

    from watchdog.observers import Observer
    from watchdog.events import *
    import time
    
    class FileEventHandler(FileSystemEventHandler):
        def __init__(self):
            FileSystemEventHandler.__init__(self)
    
        def on_moved(self, event):
            if event.is_directory:
                print("directory moved from {0} to {1}".format(event.src_path,event.dest_path))
            else:
                print("file moved from {0} to {1}".format(event.src_path,event.dest_path))
    
        def on_created(self, event):
            if event.is_directory:
                print("directory created:{0}".format(event.src_path))
            else:
                print("file created:{0}".format(event.src_path))
    
        def on_deleted(self, event):
            if event.is_directory:
                print("directory deleted:{0}".format(event.src_path))
            else:
                print("file deleted:{0}".format(event.src_path))
    
        def on_modified(self, event):
            if event.is_directory:
                print("directory modified:{0}".format(event.src_path))
            else:
                print("file modified:{0}".format(event.src_path))
    
    if __name__ == "__main__":
        observer = Observer()
        event_handler = FileEventHandler()
        observer.schedule(event_handler,"d:/dcm",True)
        observer.start()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()
    官方示例

    参考资料

    https://pythonhosted.org/watchdog/
    https://blog.csdn.net/chdhust/article/details/50514391

    作者:ckj123
    链接:https://www.jianshu.com/p/1b8560df595a
  • 相关阅读:
    hdoj 3376,2686 Matrix Again 【最小费用最大流】
    Trustie站点代码托管使用指南
    POJ 2442 Sequence(堆的使用练习)
    猛犸机器学习开发实践
    关于《金字塔原理》的主要内容
    实战案例:如何快速打造1000万+播放量的抖音网红?
    【限时特惠】网易云易盾验证码全线95折!智能无感知、滑动拼图、点选验证-7天免费体验!
    当GDPR来敲门,中国互联网企业该如何应对?
    H5活动产品设计指南基础版
    Box(视图组件)如何在多个页面不同视觉规范下的复用
  • 原文地址:https://www.cnblogs.com/-wenli/p/14077087.html
Copyright © 2011-2022 走看看