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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM