当前位置: 首页 > news >正文

[python] 基于WatchDog库实现文件系统监控

Watchdog库是Python中一个用于监控文件系统变化的第三方库。它能够实时监测文件或目录的创建、修改、删除等操作,并在这些事件发生时触发相应的处理逻辑,因此也被称为文件看门狗。

在这里插入图片描述

Watchdog库的官方仓库见:watchdog,Watchdog库的官方文档见:watchdog-doc。Watchdog库的安装命令如下:

python -m pip install -U watchdog

注意:Watchdog库最新版本(2.1.5以上版本)需在Python3.9以上版本运行。若使用Python3.4或3.5,应选用Watchdog版本低于1.0.0;若使用Python3.6至3.8,应选用Watchdog版本低于2.0.0。

文章目录

  • 1 使用示例
  • 2 参考

1 使用示例

基础示例

以下示例程序将以递归方式监控指定目录及其子文件夹中文件系统的变化情况,包括文件或文件夹的创建、修改、移动、删除,并将这些变化记录到控制台中:

import sys
# 导入logging模块,用于记录程序运行时的日志信息
import logging
# 从watchdog.observers模块中导入Observer类,用于监控文件系统的变化
from watchdog.observers import Observer
# 从watchdog.events模块中导入LoggingEventHandler类,用于处理文件系统事件并记录日志
from watchdog.events import LoggingEventHandlerif __name__ == "__main__":# 配置日志记录的基本设置# 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')# 指定要监控的文件夹路径,该文件夹必须存在path = "demo_folder"# 创建一个LoggingEventHandler对象,用于处理文件系统事件并记录日志event_handler = LoggingEventHandler()# 创建一个Observer对象,用于监控文件系统的变化observer = Observer()# 安排观察者监控指定路径下的文件系统事件# event_handler是事件处理程序# path是要监控的路径# recursive=True表示递归监控该路径下的所有子文件夹observer.schedule(event_handler, path, recursive=True)# 启动观察者,开始监控文件系统的变化observer.start()try:# 当观察者处于活动状态时,持续循环while observer.is_alive():# 等待1秒,让观察者有时间处理文件系统事件observer.join(1)finally:# 停止观察者,结束文件系统的监控observer.stop()# 等待观察者线程结束observer.join()

Watchdog事件类介绍

Watchdog库提供了一系列事件类,用于监控文件系统的各种变化,这些变化包括:

  • 创建事件on_create:涵盖文件和文件夹的创建情况,当有新的文件或者文件夹在监控路径下生成时触发相应事件。
  • 删除事件on_delete:当文件或者文件夹被从监控路径中移除时触发,分别有针对文件和文件夹的不同事件类。
  • 修改事件on_modified:文件夹内新增、删除文件或子文件夹等内容变化时触发文件夹修改事件。
  • 移动 / 重命名事件on_moved:文件或文件夹的位置发生移动,或者名称被更改时触发相应事件,该事件会记录原路径和新路径。

基于这些变化Watchdog库中存在8个事件类:

事件类名触发场景
FileCreatedEvent新文件被创建时触发
DirCreatedEvent新文件夹被创建时触发
FileDeletedEvent文件被删除时触发
DirDeletedEvent文件夹被删除时触发
FileModifiedEvent文件内容被修改时触发
DirModifiedEvent文件夹内容(如添加、删除子文件或子文件夹)发生变化时触发
FileMovedEvent文件被移动或重命名时触发
DirMovedEvent文件夹被移动或重命名时触发

注意:在某些情形下,多个Watchdog事件可能会一同触发,这往往和文件系统操作的特性以及Watchdog对这些操作的响应机制有关。例如,当移动一个文件时,会同时触发FileMovedEvent(文件移动事件)和FileDeletedEvent(文件删除事件),因为移动文件的操作在源路径上相当于删除文件,同时在目标路径上会触发FileCreatedEvent(文件创建事件)。

以下代码的主要功能是监控指定目录下文件系统的各种事件,如文件或目录的创建、删除、移动和修改,并对这些事件进行重写和相应的处理:

# 该类用于处理文件系统事件,如文件的创建、删除、修改等
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer# 定义一个自定义的文件事件处理类,继承自FileSystemEventHandler
class FileEventHandler(FileSystemEventHandler):def __init__(self):FileSystemEventHandler.__init__(self)# 初始化一个空列表,用于存储文件名self.file_names = []  # 当文件或目录被移动时触发此方法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}")# 当文件或目录被创建时触发此方法def on_created(self, event):# 判断是否是目录创建if event.is_directory:# 打印目录创建的信息print(f"目录已创建: {event.src_path}")else:# 打印文件创建的信息print(f"文件已创建: {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)# 当文件或目录被删除时触发此方法def on_deleted(self, event):# 判断是否是目录删除if event.is_directory:# 打印目录删除的信息print(f"目录已删除: {event.src_path}")else:# 打印文件删除的信息print(f"文件已删除: {event.src_path}")# 当文件或目录被修改时触发此方法,注释代码表示不触发修改事件# def on_modified(self, event):#     passif __name__ == "__main__":# 创建一个Observer对象,用于监控文件系统的变化observer = Observer()# 创建一个自定义的文件事件处理对象event_handler = FileEventHandler()# 定义要监控的目录watch_directory = "demo_folder"# 将事件处理对象和要监控的目录添加到观察者中,并设置为递归监控observer.schedule(event_handler, watch_directory, recursive=True)# 启动观察者,开始监控文件系统的变化observer.start()try:# 当观察者处于活动状态时,持续循环while observer.is_alive():# 等待1秒,让观察者有时间处理文件系统事件observer.join(1)finally:# 停止观察者,结束文件系统的监控observer.stop()# 等待观察者线程结束observer.join()

快照功能

采用基于定时器的批处理策略,合并并延迟频繁的文件变更事件,能够有效降低系统负载。具体做法是:当系统检测到文件首次变动时,启动可重置的计时器,在设定的延迟期内累积后续变更事件,待计时器超时后,再统一通过对比当前文件系统状态与上次缓存快照,可精准识别所有变更项。具体实现代码如下:

import time
import os
import threading
from watchdog.observers import Observer
from watchdog.events import *
from watchdog.utils.dirsnapshot import DirectorySnapshot, DirectorySnapshotDiffclass FileChangeHandler(FileSystemEventHandler):def __init__(self, monitored_path, delay=0.5):# 调用父类构造函数super().__init__()# 被监控的目录路径self.monitored_path = monitored_pathself.delay = delay# 定时器对象,用于延迟检查self.delay_timer = None# 快照用于记录指定目录在某个时间点的状态,包含了目录下所有文件和子目录的信息,# 记录目录的初始快照self.initial_snapshot = DirectorySnapshot(self.monitored_path)def on_any_event(self, event):# 通过定时器减少不必要的检查# 如果定时器已存在,取消它if self.delay_timer:self.delay_timer.cancel()# 创建一个新的定时器,延迟后执行检查快照的操作# 通过快照检测文件系统变化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):# 打印文件和目录的创建、删除、修改和移动信息print("创建的文件:", 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("创建的目录:", diff.dirs_created)class DirectoryMonitor:def __init__(self, monitored_path):# 被监控的目录路径self.monitored_path = monitored_path# 创建一个观察者对象self.directory_observer = Observer()def start_monitoring(self):# 创建文件变化处理对象change_handler = FileChangeHandler(self.monitored_path)# 安排观察者监控指定目录,递归地监控子目录self.directory_observer.schedule(change_handler, self.monitored_path, recursive=True)# 启动观察者self.directory_observer.start()def stop_monitoring(self):# 停止观察者self.directory_observer.stop()# 等待观察者线程结束self.directory_observer.join()if __name__ == "__main__":monitor = DirectoryMonitor("demo_folder")# 开始监控monitor.start_monitoring()try:while True:time.sleep(1)except KeyboardInterrupt:monitor.stop_monitoring()

多文件夹监控

以下代码展示了通过schedule方法为每个目录注册事件处理程序,实现对多个目录的同步监控:

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class CustomFileEventHandler(FileSystemEventHandler):def on_created(self, event):patterns = [*.jpg”, “*.png”, “*.gif”]  # 只监控图片文件    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:# 当观察者处于活动状态时,持续循环while file_observer.is_alive():# 等待1秒,让观察者有时间处理文件系统事件file_observer.join(1)finally:# 停止观察者,结束文件系统的监控file_observer.stop()# 等待观察者线程结束file_observer.join()

2 参考

  • watchdog
  • watchdog-doc
  • Python神器之使用watchdog监控文件变化
http://www.xdnf.cn/news/175249.html

相关文章:

  • PySpark中DataFrame应用升阶及UDF使用
  • Cad求多段线中心点(顶点平均值) C#
  • 利用脚本搭建私有云平台,部署云平台,发布云主机并实现互连和远程连接
  • Arduino 入门学习笔记(五):KEY实验
  • 3G大一下安卓考核题解
  • 多节点同步协同电磁频谱监测任务分配方法简要介绍
  • CDA Edit 的设计
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第四模块·Java特性专精 —— 第十五章 泛型:类型系统的元编程革命
  • 编译原理实验 之 Tiny C语言编译程序实验 语法分析
  • 量子力学:量子通信
  • 人工智能时代的网络安全威胁
  • 全自动部署到远程服务器
  • 8.0 西门子PLC的S7通讯解析
  • 欧空局的P 波段雷达卫星即将升空
  • python pyplot 输出支持中文
  • Linux常用命令23——usermod
  • 关于堆栈指针的那些事 | bootloader 如何跳转app
  • react的 Fiber 节点的链表存储
  • 学生公寓限电模块控制柜是如何实现智能限电功能?
  • 【八股消消乐】发送请求有遇到服务不可用吗?如何解决?
  • 项目代码生成工具
  • 【技术追踪】基于扩散模型的脑图像反事实生成与异常检测(TMI-2024)
  • 【计算机视觉】CV实战项目- Four-Flower:基于TensorFlow的花朵分类实战指南
  • HarmonyOS NEXT:多设备的自由流转
  • 前端Vue项目处理跨域请求问题解决方案(后端未加cors),前端调后端
  • 深入探索Python Pandas:解锁数据分析的无限可能
  • go语言八股文(四)
  • WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换Java代码
  • 电池管理系统
  • Linux文件管理(3)