watchdog
是一个用于监控文件系统事件的 Python 库。它可以检测文件和目录的变化,如创建、修改、删除、移动等,并触发相应的事件处理。watchdog
非常适用于开发需要实时监控文件系统变化的应用,如自动化构建、日志分析、文件同步等。其主要实现或者可以说watchdog
的构件是基于以下类:
-
Observer:观察者,用于监视目录并将调用分派给事件处理程序;
-
Event handler:文件系统事件和事件处理程序;说白了,Observer监控目录,触发 Event handler 针对事件做出响应。
watchdog
库实现了一个基于操作系统文件系统事件通知机制的文件和目录变化监控系统。其核心原理如下: -
操作系统级别的通知机制:在 Linux 系统中,
watchdog
利用了inotify
内核子系统,它可以跟踪文件系统中的各种事件,如打开、关闭、读取、写入、移动、删除、创建等。在 MacOS 系统中,利用了kqueue
通知机制。在 Windows 系统中,使用的是ReadDirectoryChangesW API
来获取文件系统变动的通知。
observer = Observer()
# 观察者继承:Observer: BaseObserverSubclassCallable
#初始化操作系统选择对应系统
- 事件驱动编程:
watchdog
库通过封装上述操作系统的 API,创建了一个异步事件驱动模型。它初始化一个观察者(Observer)对象,该对象负责监视指定的文件或目录。
class EventDispatcher(BaseThread):
pass
class BaseObserver(EventDispatcher):
def __init__(self):
self._lock = threading.RLock()
#这里主要调用两个方法,def schedule() def start()
schedule将FileSystemEventHandler和监控路径关联起来
def schedule():
self._lock:
def start():
pass
- 事件调度与处理:用户定义一个继承自
FileSystemEventHandler
的类,并覆盖其中的方法(如on_modified
、on_created
、on_deleted
等),用来处理不同类型的文件系统事件。观察者将这个事件处理器与需要监控的路径相关联,并设置是否递归监控子目录。当操作系统检测到文件系统发生改变时,会发送相应的事件给watchdog
,观察者接收到这些事件后,会调用已注册的事件处理器对应的方法。
#创建文件处理类:
class FileChangeHandler(FileSystemEventHandler):
def on_created(self, event):
if event.is_directory:
return
print(f'文件创建: {event.src_path}')
def on_modified(self, event):
if event.is_directory:
return
print(f'文件修改: {event.src_path}')
def on_deleted(self, event):
if event.is_directory:
return
print(f'文件删除:{event.src_path}')
def on_moved(self, event):
if event.is_directory:
return
print(f'文件重命名:{event.src_path}')
#创建观察者
observer = Observer()
observer.schedule(event_handler, path, recursive=False)
- 线程管理:
watchdog
内部通常使用线程来监听文件系统事件,这样可以在主线程执行其他任务的同时,后台线程能够持续监听和处理文件系统变动,保证了监控的实时性。
# 调用observer.start()启动观察者线程,该线程会在后台持续监听文件系统事件
observer.start()
总的来说,watchdog
库通过底层的操作系统接口监听文件系统事件,然后通过事件驱动的方式,让开发者能够轻松地编写响应这些事件的回调函数,从而实现对文件和目录变更的实时监控。
实际示例代码:
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class FileChangeHandler(FileSystemEventHandler):
"""
事件处理器
"""
def on_modified(self, event):
# 当文件被修改时触发此方法
if not event.is_directory:
print(f'文件 {event.src_path} 被修改')
if __name__ == "__main__":
# 要监视的目录路径
# 监控某个文件夹下哪些文件被修改
path_to_monitor = 'D:/small_project-master/small_project-master/ExcepetionDemo/logs/' # 这里可以将 '.' 替换为你要监控的实际目录路径
event_handler = FileChangeHandler()
observer = Observer()
# 将事件处理程序与要监视的路径关联起来,并设置递归监视(包括子目录)
#简述:1.先创建观察者observer = Observer();
#2.创建事件处理类FileChangeHandler继承FileSystemEventHandler,当目录被创建修改删除时用于触发对应的,文件系统事件处理类;
#2.1FileSystemEventHandler 处理流程:1.接到事件后开始触发dispatch(event),2.触发on_any_event(
# event)把事件方法进行分派处理,3.开始执行对应事件如:on_created(event),on_deleted(event), on_modified(event)
#3.观察者observer 将事件处理类和要监控的路径:path_to_monitor 进行关联,当操作系统检测到系统文件发生改变时,会发送给相应的事件给watchdog;
#4.观察者收到这些事件后,会调用事件处理类对应的方法如:on_modified, on_deleted, on_moved, on_created;
#5.调用observer.start()启动观察者线程,该线程会在后台持续监听文件系统事件
observer.schedule(event_handler, path_to_monitor, recursive=True)
observer.start() # 启动观察者
try:
while True:
time.sleep(1) # 保持程序运行,持续监听
except KeyboardInterrupt:
observer.stop() # 按 Ctrl+C 停止监听
observer.join() # 等待观察者线程结束