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:
# 當觀察者處于活動狀態(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)建情況,當有新的文件或者文件夾在監(jiān)控路徑下生成時觸發(fā)相應(yīng)事件。 - 刪除事件
on_delete:當文件或者文件夾被從監(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)。例如,當移動一個文件時,會同時觸發(fā)FileMovedEvent(文件移動事件)和FileDeletedEvent(文件刪除事件),因為移動文件的操作在源路徑上相當于刪除文件,同時在目標路徑上會觸發(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 = []
# 當文件或目錄被移動時觸發(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}")
# 當文件或目錄被創(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)
# 當文件或目錄被刪除時觸發(fā)此方法
def on_deleted(self, event):
# 判斷是否是目錄刪除
if event.is_directory:
# 打印目錄刪除的信息
print(f"目錄已刪除: {event.src_path}")
else:
# 打印文件刪除的信息
print(f"文件已刪除: {event.src_path}")
# 當文件或目錄被修改時觸發(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:
# 當觀察者處于活動狀態(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)負載。具體做法是:當系統(tǒng)檢測到文件首次變動時,啟動可重置的計時器,在設(shè)定的延遲期內(nèi)累積后續(xù)變更事件,待計時器超時后,再統(tǒng)一通過對比當前文件系統(tǒng)狀態(tài)與上次緩存快照,可精準識別所有變更項。具體實現(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):
# 獲取當前目錄的新快照
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:
# 當觀察者處于活動狀態(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-01
python通過imaplib模塊讀取gmail里郵件的方法
這篇文章主要介紹了python通過imaplib模塊讀取gmail里郵件的方法,涉及Python操作imaplib模塊操作郵件的相關(guān)技巧,需要的朋友可以參考下2015-05-05
Python爬蟲實戰(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

