官網:https://pythonhosted.org/watchdog/
需求:根據項目需求要寫一個檔案監控的程式,來學習一下這個庫。
介紹:
watchdog用來監控指定目錄/檔案的變化,如添加删除檔案或目錄、修改檔案内容、重命名檔案或目錄等,每種變化都會産生一個事件,且有一個特定的事件類與之對應,然後再通過事件處理類來處理對應的事件,怎麼樣處理事件完全可以自定義,隻需繼承事件處理類的基類并重寫對應執行個體方法。使用方法(根據官網給出的簡單介紹常用的兩個方法):
- Create an instance of the
thread class.watchdog.observers.Observer
- Implement a subclass of
(or as in our case, we will use the built-inwatchdog.events.FileSystemEventHandler
, which already does).watchdog.events.LoggingEventHandler
- Schedule monitoring a few paths with the
instance attaching theobserver
.event handler
- Start the
thread and wait for it generate events without blocking our main thread.observer
官網案例:
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()
events:
主要的内容都在events這個檔案裡面,包含了所有的可監聽的事件.
使用案例:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from __future__ import print_function
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
WATCH_PATH = 'D:/test' # 監控目錄
class FileMonitorHandler(FileSystemEventHandler):
def __init__(self, **kwargs):
super(FileMonitorHandler, self).__init__(**kwargs)
# 監控目錄 目錄下面以device_id為目錄存放各自的圖檔
self._watch_path = WATCH_PATH
# 重寫檔案改變函數,檔案改變都會觸發檔案夾變化
def on_modified(self, event):
if not event.is_directory: # 檔案改變都會觸發檔案夾變化
file_path = event.src_path
print("檔案改變: %s " % file_path)
def on_created(self, event):
print( '建立了檔案夾', event.src_path)
def on_moved(self, event):
print("移動了檔案",event.src_path)
def on_deleted(self, event):
print("删除了檔案", event.src_path)
def on_any_event(self, event):
print("都會觸發")
if __name__ == "__main__":
event_handler = FileMonitorHandler()
observer = Observer()
observer.schedule(event_handler, path=WATCH_PATH, recursive=True) # recursive遞歸的
observer.start()
observer.join()
watchdog.events.FileSystemEventHandler()
事件處理器的基類,用于處理事件,使用者需繼承該類,并在子類中重寫對應方法。
類執行個體方法如下:
-
self.dispatch(event)
接收到一個事件後,通過該方法來決定該event由下面哪個方法處理.
def dispatch(self, event):
"""Dispatches events to the appropriate methods.
:param event:
The event object representing the file system event.
:type event:
:class:`FileSystemEvent`
"""
self.on_any_event(event)
_method_map = {
EVENT_TYPE_MODIFIED: self.on_modified,
EVENT_TYPE_MOVED: self.on_moved,
EVENT_TYPE_CREATED: self.on_created,
EVENT_TYPE_DELETED: self.on_deleted,
}
event_type = event.event_type
_method_map[event_type](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線程