python基于watchdog庫實現(xiàn)文件系統(tǒng)監(jiān)控
Watchdog庫是Python中一個用于監(jiān)控文件系統(tǒng)變化的第三方庫。它能夠?qū)崟r監(jiān)測文件或目錄的創(chuàng)建、修改、刪除等操作,并在這些事件發(fā)生時觸發(fā)相應(yīng)的處理邏輯,因此也被稱為文件看門狗。
Watchdog庫的官方倉庫見:watchdog,Watchdog庫的官方文檔見:watchdog-doc。Watchdog庫的安裝命令如下:
python -m pip install -U watchdog
注意:Watchdog庫最新版本(2.1.5以上版本)需在Python3.9以上版本運行。若使用Python3.4或3.5,應(yīng)選用Watchdog版本低于1.0.0;若使用Python3.6至3.8,應(yīng)選用Watchdog版本低于2.0.0。
1 使用示例
基礎(chǔ)示例
以下示例程序?qū)⒁赃f歸方式監(jiān)控指定目錄及其子文件夾中文件系統(tǒng)的變化情況,包括文件或文件夾的創(chuàng)建、修改、移動、刪除,并將這些變化記錄到控制臺中:
import sys # 導(dǎo)入logging模塊,用于記錄程序運行時的日志信息 import logging # 從watchdog.observers模塊中導(dǎo)入Observer類,用于監(jiān)控文件系統(tǒng)的變化 from watchdog.observers import Observer # 從watchdog.events模塊中導(dǎo)入LoggingEventHandler類,用于處理文件系統(tǒng)事件并記錄日志 from watchdog.events import LoggingEventHandler if __name__ == "__main__": # 配置日志記錄的基本設(shè)置 # level=logging.INFO表示只記錄INFO級別及以上的日志信息 # format='%(asctime)s - %(message)s'指定日志的輸出格式,包含時間戳和日志消息 # datefmt='%Y-%m-%d %H:%M:%S'指定時間戳的格式 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # 指定要監(jiān)控的文件夾路徑,該文件夾必須存在 path = "demo_folder" # 創(chuàng)建一個LoggingEventHandler對象,用于處理文件系統(tǒng)事件并記錄日志 event_handler = LoggingEventHandler() # 創(chuàng)建一個Observer對象,用于監(jiān)控文件系統(tǒng)的變化 observer = Observer() # 安排觀察者監(jiān)控指定路徑下的文件系統(tǒng)事件 # event_handler是事件處理程序 # path是要監(jiān)控的路徑 # recursive=True表示遞歸監(jiān)控該路徑下的所有子文件夾 observer.schedule(event_handler, path, recursive=True) # 啟動觀察者,開始監(jiān)控文件系統(tǒng)的變化 observer.start() try: # 當(dāng)觀察者處于活動狀態(tài)時,持續(xù)循環(huán) while observer.is_alive(): # 等待1秒,讓觀察者有時間處理文件系統(tǒng)事件 observer.join(1) finally: # 停止觀察者,結(jié)束文件系統(tǒng)的監(jiān)控 observer.stop() # 等待觀察者線程結(jié)束 observer.join()
Watchdog事件類介紹
Watchdog庫提供了一系列事件類,用于監(jiān)控文件系統(tǒng)的各種變化,這些變化包括:
- 創(chuàng)建事件
on_create
:涵蓋文件和文件夾的創(chuàng)建情況,當(dāng)有新的文件或者文件夾在監(jiān)控路徑下生成時觸發(fā)相應(yīng)事件。 - 刪除事件
on_delete
:當(dāng)文件或者文件夾被從監(jiān)控路徑中移除時觸發(fā),分別有針對文件和文件夾的不同事件類。 - 修改事件
on_modified
:文件夾內(nèi)新增、刪除文件或子文件夾等內(nèi)容變化時觸發(fā)文件夾修改事件。 - 移動 / 重命名事件
on_moved
:文件或文件夾的位置發(fā)生移動,或者名稱被更改時觸發(fā)相應(yīng)事件,該事件會記錄原路徑和新路徑。
基于這些變化Watchdog庫中存在8個事件類:
事件類名 | 觸發(fā)場景 |
---|---|
FileCreatedEvent | 新文件被創(chuàng)建時觸發(fā) |
DirCreatedEvent | 新文件夾被創(chuàng)建時觸發(fā) |
FileDeletedEvent | 文件被刪除時觸發(fā) |
DirDeletedEvent | 文件夾被刪除時觸發(fā) |
FileModifiedEvent | 文件內(nèi)容被修改時觸發(fā) |
DirModifiedEvent | 文件夾內(nèi)容(如添加、刪除子文件或子文件夾)發(fā)生變化時觸發(fā) |
FileMovedEvent | 文件被移動或重命名時觸發(fā) |
DirMovedEvent | 文件夾被移動或重命名時觸發(fā) |
注意:在某些情形下,多個Watchdog事件可能會一同觸發(fā),這往往和文件系統(tǒng)操作的特性以及Watchdog對這些操作的響應(yīng)機制有關(guān)。例如,當(dāng)移動一個文件時,會同時觸發(fā)FileMovedEvent(文件移動事件)和FileDeletedEvent(文件刪除事件),因為移動文件的操作在源路徑上相當(dāng)于刪除文件,同時在目標(biāo)路徑上會觸發(fā)FileCreatedEvent(文件創(chuàng)建事件)。
以下代碼的主要功能是監(jiān)控指定目錄下文件系統(tǒng)的各種事件,如文件或目錄的創(chuàng)建、刪除、移動和修改,并對這些事件進行重寫和相應(yīng)的處理:
# 該類用于處理文件系統(tǒng)事件,如文件的創(chuàng)建、刪除、修改等 from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer # 定義一個自定義的文件事件處理類,繼承自FileSystemEventHandler class FileEventHandler(FileSystemEventHandler): def __init__(self): FileSystemEventHandler.__init__(self) # 初始化一個空列表,用于存儲文件名 self.file_names = [] # 當(dāng)文件或目錄被移動時觸發(fā)此方法 def on_moved(self, event): # 判斷是否是目錄移動 if event.is_directory: # 打印目錄移動的信息 print(f"目錄從 {event.src_path} 移動到 {event.dest_path}") else: # 打印文件移動的信息 print(f"文件從 {event.src_path} 移動到 {event.dest_path}") # 當(dāng)文件或目錄被創(chuàng)建時觸發(fā)此方法 def on_created(self, event): # 判斷是否是目錄創(chuàng)建 if event.is_directory: # 打印目錄創(chuàng)建的信息 print(f"目錄已創(chuàng)建: {event.src_path}") else: # 打印文件創(chuàng)建的信息 print(f"文件已創(chuàng)建: {event.src_path}") # 從文件的完整路徑中提取文件名 file_full_name = str(event.src_path.split('/')[-1]) if file_full_name.endswith('.csv'): # 如果是csv文件,將其添加到文件名列表中 self.file_names.append(file_full_name) # 打印文件名列表 print(self.file_names) # 當(dāng)文件或目錄被刪除時觸發(fā)此方法 def on_deleted(self, event): # 判斷是否是目錄刪除 if event.is_directory: # 打印目錄刪除的信息 print(f"目錄已刪除: {event.src_path}") else: # 打印文件刪除的信息 print(f"文件已刪除: {event.src_path}") # 當(dāng)文件或目錄被修改時觸發(fā)此方法,注釋代碼表示不觸發(fā)修改事件 # def on_modified(self, event): # pass if __name__ == "__main__": # 創(chuàng)建一個Observer對象,用于監(jiān)控文件系統(tǒng)的變化 observer = Observer() # 創(chuàng)建一個自定義的文件事件處理對象 event_handler = FileEventHandler() # 定義要監(jiān)控的目錄 watch_directory = "demo_folder" # 將事件處理對象和要監(jiān)控的目錄添加到觀察者中,并設(shè)置為遞歸監(jiān)控 observer.schedule(event_handler, watch_directory, recursive=True) # 啟動觀察者,開始監(jiān)控文件系統(tǒng)的變化 observer.start() try: # 當(dāng)觀察者處于活動狀態(tài)時,持續(xù)循環(huán) while observer.is_alive(): # 等待1秒,讓觀察者有時間處理文件系統(tǒng)事件 observer.join(1) finally: # 停止觀察者,結(jié)束文件系統(tǒng)的監(jiān)控 observer.stop() # 等待觀察者線程結(jié)束 observer.join()
2.快照功能
采用基于定時器的批處理策略,合并并延遲頻繁的文件變更事件,能夠有效降低系統(tǒng)負載。具體做法是:當(dāng)系統(tǒng)檢測到文件首次變動時,啟動可重置的計時器,在設(shè)定的延遲期內(nèi)累積后續(xù)變更事件,待計時器超時后,再統(tǒng)一通過對比當(dāng)前文件系統(tǒng)狀態(tài)與上次緩存快照,可精準(zhǔn)識別所有變更項。具體實現(xiàn)代碼如下:
import time import os import threading from watchdog.observers import Observer from watchdog.events import * from watchdog.utils.dirsnapshot import DirectorySnapshot, DirectorySnapshotDiff class FileChangeHandler(FileSystemEventHandler): def __init__(self, monitored_path, delay=0.5): # 調(diào)用父類構(gòu)造函數(shù) super().__init__() # 被監(jiān)控的目錄路徑 self.monitored_path = monitored_path self.delay = delay # 定時器對象,用于延遲檢查 self.delay_timer = None # 快照用于記錄指定目錄在某個時間點的狀態(tài),包含了目錄下所有文件和子目錄的信息, # 記錄目錄的初始快照 self.initial_snapshot = DirectorySnapshot(self.monitored_path) def on_any_event(self, event): # 通過定時器減少不必要的檢查 # 如果定時器已存在,取消它 if self.delay_timer: self.delay_timer.cancel() # 創(chuàng)建一個新的定時器,延遲后執(zhí)行檢查快照的操作 # 通過快照檢測文件系統(tǒng)變化 self.delay_timer = threading.Timer(self.delay, self._check_directory_changes) self.delay_timer.start() def _check_directory_changes(self): # 獲取當(dāng)前目錄的新快照 new_snapshot = DirectorySnapshot(self.monitored_path) # 計算新舊快照之間的差異 snapshot_difference = DirectorySnapshotDiff(self.initial_snapshot, new_snapshot) # 更新初始快照為新快照 self.initial_snapshot = new_snapshot # 清空定時器 self.delay_timer = None # 打印目錄變化信息 self._print_changes(snapshot_difference) def _print_changes(self, diff): # 打印文件和目錄的創(chuàng)建、刪除、修改和移動信息 print("創(chuàng)建的文件:", diff.files_created) print("刪除的文件:", diff.files_deleted) print("修改的文件:", diff.files_modified) print("移動的文件:", diff.files_moved) print("修改的目錄:", diff.dirs_modified) print("移動的目錄:", diff.dirs_moved) print("刪除的目錄:", diff.dirs_deleted) print("創(chuàng)建的目錄:", diff.dirs_created) class DirectoryMonitor: def __init__(self, monitored_path): # 被監(jiān)控的目錄路徑 self.monitored_path = monitored_path # 創(chuàng)建一個觀察者對象 self.directory_observer = Observer() def start_monitoring(self): # 創(chuàng)建文件變化處理對象 change_handler = FileChangeHandler(self.monitored_path) # 安排觀察者監(jiān)控指定目錄,遞歸地監(jiān)控子目錄 self.directory_observer.schedule(change_handler, self.monitored_path, recursive=True) # 啟動觀察者 self.directory_observer.start() def stop_monitoring(self): # 停止觀察者 self.directory_observer.stop() # 等待觀察者線程結(jié)束 self.directory_observer.join() if __name__ == "__main__": monitor = DirectoryMonitor("demo_folder") # 開始監(jiān)控 monitor.start_monitoring() try: while True: time.sleep(1) except KeyboardInterrupt: monitor.stop_monitoring()
3.多文件夾監(jiān)控
以下代碼展示了通過schedule方法為每個目錄注冊事件處理程序,實現(xiàn)對多個目錄的同步監(jiān)控:
from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class CustomFileEventHandler(FileSystemEventHandler): def on_created(self, event): patterns = [“*.jpg”, “*.png”, “*.gif”] # 只監(jiān)控圖片文件 def on_modified(self, event): print(f“圖片文件有變化:{event.src_path}”) entity = "directory" if event.is_directory else "file" print(f"{entity} on_created: {event.src_path}") if __name__ == "__main__": file_observer = Observer() monitored_directories = ['demo_folder', 'demo_folder2'] file_event_handler = CustomFileEventHandler() for directory in monitored_directories: # 為每個目錄注冊事件處理程序 file_observer.schedule(file_event_handler, directory, recursive=True) file_observer.start() try: # 當(dāng)觀察者處于活動狀態(tài)時,持續(xù)循環(huán) while file_observer.is_alive(): # 等待1秒,讓觀察者有時間處理文件系統(tǒng)事件 file_observer.join(1) finally: # 停止觀察者,結(jié)束文件系統(tǒng)的監(jiān)控 file_observer.stop() # 等待觀察者線程結(jié)束 file_observer.join()
到此這篇關(guān)于python基于watchdog庫實現(xiàn)文件系統(tǒng)監(jiān)控的文章就介紹到這了,更多相關(guān)python watchdog文件系統(tǒng)監(jiān)控內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實現(xiàn)加解密,編碼解碼和進制轉(zhuǎn)換(最全版)
這篇文章主要為大家詳細介紹了Python實現(xiàn)加解密、編碼解碼、進制轉(zhuǎn)換、字符串轉(zhuǎn)換的最全版操作方法,文中的示例代碼講解詳細,大家可以收藏一下2023-01-01python通過imaplib模塊讀取gmail里郵件的方法
這篇文章主要介紹了python通過imaplib模塊讀取gmail里郵件的方法,涉及Python操作imaplib模塊操作郵件的相關(guān)技巧,需要的朋友可以參考下2015-05-05Python爬蟲實戰(zhàn)演練之采集糗事百科段子數(shù)據(jù)
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Python采集糗事百科段子的數(shù)據(jù),大家可以在過程中查缺補漏,提升水平2021-10-10利用Python模擬登錄pastebin.com的實現(xiàn)方法
這篇文章主要介紹了利用Python模擬登錄pastebin.com的實現(xiàn)方法,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-07-07