当前位置: 代码网 > it编程>前端脚本>Python > Python使用Watchdog库监听文件变化

Python使用Watchdog库监听文件变化

2026年01月16日 Python 我要评论
一、简介官方文档:https://python-watchdog.readthedocs.io/en/stable/index.htmlwatchdog 是 python 生态中处理文件系统事件的主流

一、简介

官方文档:https://python-watchdog.readthedocs.io/en/stable/index.html

watchdog 是 python 生态中处理文件系统事件的主流库,跨平台(windows/linux/macos)、效率高,支持监听文件 / 目录的创建、修改、删除、移动等事件,是工业级的解决方案。

# 安装
pip install watchdog

二、使用

核心组件:
eventhandler 事件处理器:定义监控到文件事件后要执行的逻辑(核心,需自定义 / 继承)
observer 观察者:负责启动监控线程,监听文件系统事件,并将事件分发给处理器
filesystemevent 事件对象:包含事件类型(创建 / 修改等)、文件路径、是否是目录等信息

watchdog基于系统原生的文件监控接口(如 linux 的 inotify、windows 的 readdirectorychangesw),性能远高于手动轮询;
对于频繁修改的文件(如每秒多次修改),可能会触发多次on_modified事件,可通过加时间戳防抖处理;
跨平台使用时,路径建议用os.path.abspath()转为绝对路径,避免兼容问题。

1、监听单个目录的所有文件事件

运行代码前,先创建./test_dir目录;

import time
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

# 自定义事件处理器:继承filesystemeventhandler,重写对应事件方法
class myfilehandler(filesystemeventhandler):
    # 监听文件/目录创建事件
    def on_created(self, event):
        # event.is_directory 判断是否是目录,event.src_path 是触发事件的文件路径
        if event.is_directory:
            print(f"[创建目录] {event.src_path}")
        else:
            print(f"[创建文件] {event.src_path}")

    # 监听文件/目录修改事件
    def on_modified(self, event):
        if not event.is_directory:  # 只关注文件修改(排除目录修改)
            print(f"[修改文件] {event.src_path}")

    # 监听文件/目录删除事件
    def on_deleted(self, event):
        if event.is_directory:
            print(f"[删除目录] {event.src_path}")
        else:
            print(f"[删除文件] {event.src_path}")

    # 监听文件/目录移动事件
    def on_moved(self, event):
        # event.dest_path 是移动后的路径
        if event.is_directory:
            print(f"[移动目录] {event.src_path} -> {event.dest_path}")
        else:
            print(f"[移动文件] {event.src_path} -> {event.dest_path}")

if __name__ == "__main__":
    # 要监控的目录路径(绝对路径/相对路径都可)
    monitor_dir = "./test_dir"
    # 创建事件处理器实例
    event_handler = myfilehandler()
    # 创建观察者实例
    observer = observer()
    # 为观察者绑定处理器和监控目录
    # recursive=false 表示只监控当前目录,不包含子目录
    observer.schedule(event_handler, path=monitor_dir, recursive=false)
    
    # 启动观察者(后台线程,非阻塞)
    observer.start()
    print(f"开始监控目录:{monitor_dir}(按 ctrl+c 停止)")
    
    try:
        # 保持主线程运行,避免程序退出
        while true:
            time.sleep(1)
    except keyboardinterrupt:
        # 捕获 ctrl+c,停止观察者
        observer.stop()
        print("\n停止监控")
    # 等待观察者线程结束
    observer.join()

2、监听特定类型文件(如.txt)

仅监控 ./test_dir下.txt文件的修改事件,忽略其他类型文件。

import time
import os
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

class txtfilehandler(filesystemeventhandler):
    # 重写修改事件,增加文件类型过滤
    def on_modified(self, event):
        # 排除目录,只处理文件
        if not event.is_directory:
            # 获取文件后缀名
            file_ext = os.path.splitext(event.src_path)[1]
            # 只处理 .txt 文件
            if file_ext == ".txt":
                print(f"[修改txt文件] {event.src_path}")

if __name__ == "__main__":
    monitor_dir = "./test_dir"
    handler = txtfilehandler()
    observer = observer()
    observer.schedule(handler, monitor_dir, recursive=false)
    observer.start()
    
    print(f"开始监控 {monitor_dir} 下的 .txt 文件修改(按 ctrl+c 停止)")
    try:
        while true:
            time.sleep(1)
    except keyboardinterrupt:
        observer.stop()
    observer.join()

3、递归监控 - 监听目录及所有子目录

import time
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

class recursivehandler(filesystemeventhandler):
    def on_created(self, event):
        print(f"[创建] {event.src_path} (目录: {event.is_directory})")

if __name__ == "__main__":
    monitor_dir = "./test_dir"
    handler = recursivehandler()
    observer = observer()
    # 关键:recursive=true 开启递归监控
    observer.schedule(handler, monitor_dir, recursive=true)
    observer.start()
    
    print(f"递归监控 {monitor_dir} 及其所有子目录(按 ctrl+c 停止)")
    try:
        while true:
            time.sleep(1)
    except keyboardinterrupt:
        observer.stop()
    observer.join()

4、应用:监控到文件修改后自动执行脚本

监控配置文件 ./config.ini,当文件修改后,自动重新加载配置并执行指定脚本(如重启服务、刷新缓存)。

import time
import subprocess
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

class configchangehandler(filesystemeventhandler):
    def on_modified(self, event):
        # 只监控 config.ini 文件
        if event.src_path.endswith("config.ini") and not event.is_directory:
            print(f"\n[配置文件修改] {event.src_path}")
            print("开始重新加载配置并执行脚本...")
            
            # 自定义动作1:打印配置内容(模拟加载配置)
            with open(event.src_path, "r", encoding="utf-8") as f:
                config_content = f.read()
                print(f"最新配置内容:\n{config_content}")
            
            # 自定义动作2:执行外部脚本(如 restart_service.py)
            # 注意:需提前创建 restart_service.py,或替换为你的脚本路径
            try:
                result = subprocess.run(
                    ["python", "restart_service.py"],
                    capture_output=true,
                    text=true,
                    timeout=10
                )
                print(f"脚本执行结果:\nstdout: {result.stdout}\nstderr: {result.stderr}")
            except exception as e:
                print(f"脚本执行失败:{e}")

if __name__ == "__main__":
    monitor_dir = "./"  # 监控当前目录
    handler = configchangehandler()
    observer = observer()
    observer.schedule(handler, monitor_dir, recursive=false)
    observer.start()
    
    print(f"监控配置文件 config.ini 修改(按 ctrl+c 停止)")
    try:
        while true:
            time.sleep(1)
    except keyboardinterrupt:
        observer.stop()
    observer.join()

5、监控多个目录 - 同时监听不同路径

同时监控./log_dir./config_dir两个目录的文件变化

import time
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

class multidirhandler(filesystemeventhandler):
    def on_created(self, event):
        # 区分不同目录的事件
        if "log_dir" in event.src_path:
            print(f"[日志目录] 新增文件/目录:{event.src_path}")
        elif "config_dir" in event.src_path:
            print(f"[配置目录] 新增文件/目录:{event.src_path}")

if __name__ == "__main__":
    # 定义多个监控目录
    dir1 = "./log_dir"
    dir2 = "./config_dir"
    
    handler = multidirhandler()
    observer = observer()
    
    # 为观察者添加多个监控任务
    observer.schedule(handler, dir1, recursive=false)
    observer.schedule(handler, dir2, recursive=false)
    
    observer.start()
    print(f"同时监控 {dir1} 和 {dir2}(按 ctrl+c 停止)")
    
    try:
        while true:
            time.sleep(1)
    except keyboardinterrupt:
        observer.stop()
    observer.join()

6、动态启停监控 - 暂停 / 恢复文件监控

支持手动触发暂停监控,一段时间后恢复(比如临时维护目录时暂停监控)。

import time
import threading
from watchdog.observers import observer
from watchdog.events import filesystemeventhandler

class simplehandler(filesystemeventhandler):
    def on_modified(self, event):
        if not event.is_directory:
            print(f"[监控中] 修改文件:{event.src_path}")

def control_observer(observer):
    """单独线程处理监控的启停控制"""
    while true:
        cmd = input("\n输入命令(pause/continue/exit):").strip().lower()
        if cmd == "pause":
            observer.stop()  # 暂停监控
            print("监控已暂停")
        elif cmd == "continue":
            observer.start()  # 恢复监控
            print("监控已恢复")
        elif cmd == "exit":
            observer.stop()
            print("退出程序")
            break
        else:
            print("无效命令,请输入 pause/continue/exit")

if __name__ == "__main__":
    monitor_dir = "./test_dir"
    handler = simplehandler()
    observer = observer()
    observer.schedule(handler, monitor_dir, recursive=false)
    observer.start()
    
    print(f"开始监控 {monitor_dir}(可输入命令控制)")
    # 启动控制线程,避免阻塞主线程
    control_thread = threading.thread(target=control_observer, args=(observer,))
    control_thread.daemon = true  # 主线程退出时,控制线程也退出
    control_thread.start()
    
    # 等待控制线程结束
    control_thread.join()
    observer.join()

到此这篇关于python使用watchdog库监听文件变化的文章就介绍到这了,更多相关python watchdog监听文件变化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com