在实际的开发过程中,有时候需要通过 Python 去监听某文件夹的变动,从而实现针对文件变化的操作。
Python 中有2个不错的库实现了该功能,分别是 pyinotifywatchdog 本篇博客为你介绍第三方模块 watchdog 实现对文件夹的监控。

文章目录

  • watchdog 安装与准备
    • 官方提供最简单的入门案例
  • 重写事件
  • 监听指定内容
  • 添加多个事件
  • 监听特定文件夹,特定后缀的文件
  • 记录时间

watchdog 安装与准备

安装就比较简单了

pip install watchdog

项目地址是:https://pypi.org/project/watchdog/#description
文档参考地址:https://python-watchdog.readthedocs.io/en/stable/

watchdog 是一个实时监控库,其原理是通过操作系统的时间触发,需要循环等待。

官方提供最简单的入门案例

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandlerif __name__ == "__main__":logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')path = sys.argv[1] if len(sys.argv) > 1 else '.'event_handler = LoggingEventHandler()observer = Observer()observer.schedule(event_handler, path, recursive=True)observer.start()try:while True:time.sleep(1)finally:observer.stop()observer.join()

基于上述源码,说明一下 watchdog 的相关用法。

observer = Observer()
创建一个观察者对象。

observer.schedule()
声明一个定时任务。

observer.start()
启动定时任务。

observer.schedule() 的函数原型如下

schedule(event_handler, path, recursive=False)

该方法用于监视 path 路径,并调用给定的事情 event_handler

最后一个参数 recursive 表示是否递归子目录,即监听子目录,默认为 False。

start()
启动线程,这里开启了新的守护线程,主程序如果结束, 该线程也会停止。

每个线程对象只能调用1次,它安排对象的 run() 方法在单独的控制线程中调用,如果在同一线程对象上多次调用此方法将引发RuntimeError

重写事件

接下来我们使用自定义的时间,实现对文件操作的监控

import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandlerclass MyEventHandler(FileSystemEventHandler):# 文件移动def on_moved(self, event):print("文件移动触发")print(event)def on_created(self, event):print("文件创建触发")print(event)def on_deleted(self, event):print("文件删除触发")print(event)def on_modified(self, event):print("文件编辑触发")print(event)if __name__ == '__main__':observer = Observer()  # 创建观察者对象file_handler = MyEventHandler()  # 创建事件处理对象observer.schedule(file_handler, "./images", False)  # 向观察者对象绑定事件和目录observer.start() # 启动try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()

这里会出现一个问题,就是当复制进去一个文件时,会同时触发 创建/编辑 事件,如下所示。

先说原因:
文件创建这个操作会触发多种事件,包括 FileCreatedEventFileModifiedEvent 事件,对应到代码中就是 on_createdon_modified 方法被调用,其原因在于 f = open("file.txt", "w") 这样文件创建动作会触发 FileCreatedEvent 事件,执行 on_created 函数,往文件写数据的 f.flush()f.close() 操作,会触发 FileModifiedEvent 事件,执行 on_modified 函数,所以触发了 3次。

FileSystemEvent 文件类派生出来的子类包括如下内容

  • watchdog.events.FileCreatedEvent() :文件被创建时触发该事件;
  • watchdog.events.DirCreatedEvent() :目录被创建时触发该事件;
  • watchdog.events.FileDeletedEvent() :文件被删除时触发该事件;
  • watchdog.events.DirDeletedEvent() :目录被删除时触发该事件;
  • watchdog.events.FileModifiedEvent() :文件被修改时触发该事件;
  • watchdog.events.DirModifiedEvent() :目录被修改时触发该事件;
  • watchdog.events.FileMovedEvent() :文件被移动或重命名时触发该事件(event.src_path 表示原路径,还有 event.dest_path );
  • watchdog.events.DirMovedEvent() :目录被移动或重命名时触发该事件(event.src_path 表示原路径,还有 event.dest_path );

watchdog 默认提供的一些事件处理类

  • FileSystemEventHandler:文件,事件处理器的基类,用于处理事件;
  • PatternMatchingEventHandler:模式匹配文件;
  • RegexMatchingEventHandler:正则匹配文件;
  • LoggingEventHandler:记录日志。

PatternMatchingEventHandler 函数原型如下

watchdog.events.PatternMatchingEventHandler(patterns=None,ignore_patterns=None,ignore_directories=False, case_sensitive=False)

该类会检查触发事件的 src_pathdest_path ,是否与 patterns 指定的模式匹配;

  • ignore_patterns :需要排除不处理的模式,如果路径匹配该模式则不处理
  • ignore_directories:为 True 表示不处理由目录引起的事件;
  • case_sensitive:为 True 则表示路径不区分大小写。

RegexMatchingEventHandler 函数原型如下

watchdog.events.RegexMatchingEventHandler(regexes=[r".*"], ignore_regexes=[], ignore_directories=False,  case_sensitive=False)

监听指定内容

继承监听事件函数,然后监听特定文件。

import time
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandlerclass MyHandler(FileSystemEventHandler):def on_modified(self, event):print(dir(event))print(event.src_path)path = os.path.abspath(event.src_path)print(path)if path == r"F:\xxx\监控文件变动\imgs\1.log":  # 监控指定文件print("文件 %s 有编辑" % event.src_path)if __name__ == "__main__":event_handler = MyHandler()observer = Observer()observer.schedule(event_handler, path='./imgs', recursive=False)observer.start()try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()

其中 event 对象的属性如下所示:

  • event.is_directory:该事件是否由一个目录触发;
  • event.src_path:触发该事件的文件或目录路径;
  • event.event_type:事件类型,例如 moveddeletedcreatedmodified
  • event.key:元组格式返回 (event_type, src_path, is_directory)

observer.schedule(event_handler, path, recursive=False) 的详细说明
每一次调用 schedule() 对一个路径( path )进行监控处理叫做 watchschedule() 方法会返回这个 watch ,我们可以对 watch 增加多个 event 事件处理器。

  • observer.add_handler_for_watch(event_handler, watch):添加1个新的事件处理器到 ;
  • observer.remove_handler_for_watch(event_handler, watch):从 watch 移除1个事件处理器;
  • observer.unschedule(watch):移除1个 watch 及其所有事件处理器;
  • observer.unschedule_all():移除所有 watch 及关联的事件处理器;
  • observer.on_thread_stop():等同于 observer.stop()

添加多个事件

import time
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, LoggingEventHandlerclass MyHandler(FileSystemEventHandler):def on_created(self, event):print(event)if __name__ == "__main__":event_handler1 = MyHandler()observer = Observer()watch = observer.schedule(event_handler1, path='.', recursive=True)logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')event_handler2 = LoggingEventHandler()observer.add_handler_for_watch(event_handler2, watch)  # 添加event handlerobserver.start()try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()

监听特定文件夹,特定后缀的文件

import time
import logging
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, LoggingEventHandlerlogging.basicConfig(level=logging.INFO, filename='./video_log.log', filemode='a+', format='%(asctime)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S', encoding="utf-8")class LogHandler(LoggingEventHandler):def on_created(self, event):path = event.src_pathif event.is_directory:passelse:logging.info(path + "文件新增")class MyHandler(FileSystemEventHandler):def on_created(self, event):path = event.src_pathfile_name = os.path.basename(path)if file_name.endswith("mp4") or file_name.endswith("avi") or file_name.endswith("flv"):print("文件格式正确")else:passprint(event)if __name__ == "__main__":event_handler = MyHandler()observer = Observer()watch = observer.schedule(event_handler, path='./videos', recursive=False)log_handler = LogHandler()observer.add_handler_for_watch(log_handler, watch)  # 写入日志observer.start()try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()

记录时间

今天是持续写作的第 283 / 365 天。
可以关注我,点赞我、评论我、收藏我啦。

更多精彩

  • Python 爬虫 100 例教程导航帖(连续 3 年,不断更!)

python 监目录文件变动,然后在做些其它的操作,watchdog 详细解答相关推荐

  1. Python监控目录文件夹,并使用SFTP上传目录及文件到linux服务器

    Python 扫描监控本地文件夹并进行超大文件上传 方案1:WebUploader大文件分块多线程并发上传 方案2:watchdog目录文件夹监控,paramiko STFP上传服务器 方案3:优化2 ...

  2. python监听文件最后修改人_Python持续监听文件变化代码实例

    在日常的工作中,有时候会有这样的需求,需要一个常驻任务,持续的监听一个目录下文件的变化,对此作出回应. pyinotify就是这样的一个python包,使用方式如下: 一旦src.txt有新的内容,程 ...

  3. Python为何如此受欢迎?你真的需要学习Python嘛?学了之后能做些什么?

    Python是一门代码简单.易读易写的编程语言. 近年来,它是一种在 AI 开发中受到关注的编程语言,并且由于有专门用于机器学习的库,因此它已被用作 AI 开发的标准语言.此外由于它简单易懂,因此经常 ...

  4. python监听文件更改记录_python 监控文件修改

    Pyinotify – Linux中实时监控文件系统更改 Pyinotify 是一个简单而实用的 Python 模块,它用于通过 inotify 实时监控Linux文件系统的更改.用于在Linux中实 ...

  5. Python压缩目录文件夹,解压目录文件夹及耗时效率统计

    Python用zip_file压缩文件夹,用unzip_file解压文件夹 1. 压缩效果对比 发现压缩率挺低的 压缩前:28.9MB,压缩后依然:27.8MB 2. 压缩耗时 运用了Python 装 ...

  6. python监听文件更改记录_如何用机器人监听老板微信?

    随着微信社交的兴起,我们加入的群也越来越多,一个不经意就被拉入好几个群,群是大家协同交流的平台,但是微信群却越来越泛滥,不知道大家有没有统计过自己浪费在毫无营养的群中的时间? 因为群质量或者群太吵的 ...

  7. Python实现目录文件的全量和增量备份

    目标: 1.传入3个参数:源文件路径,目标文件路径,md5文件 2.每周一实现全量备份,其余时间增量备份 1.通过传入的路径,获取该路径下面的所有目录和文件(递归) 方法一:使用os.listdir ...

  8. python对csv文件的处理,pandas 数据预处理csv,案例详细

    文章目录 csv文件的导入 CSV文件的导出 不导出行号和标签,可分别将index或header设置为False 使用columns参数设置想导出的列 数据清理分组 排序 删除 缺失值处理 缺失值的删 ...

  9. python中csv文件的创建、读取、修改等操作总结

    1. python中创建新的csv文件 (1). 使用csv.writer()创建: 代码如下: import csvheaders = ['学号','姓名','分数'] rows = [('2020 ...

最新文章

  1. shell批量增删改查百库百表(mysql)
  2. Hibernate基础小案例
  3. python3之SQLAlchemy
  4. c语言数组数据的输入,在C语言中,数组中的值如何输入到函数中?
  5. Electric device abnormal detection based on IoT and knowledge graph-学习笔记
  6. frame,iframe,frameset 的区别
  7. Linux 文件属性
  8. Linux基础命令---间歇执行命令watch
  9. 关闭java程序脚本-linux
  10. SVM多分类原理学习
  11. 计算机软件图标不正常,桌面图标显示不正常,详细教您桌面图标显示不正常怎么解决...
  12. 计算机Excel及格率怎么,及格率怎么算在excel里?
  13. 默孚龙电滑环,360度旋转防止绕线
  14. 沟通书籍排行榜前十名 提高沟通能力的十大书籍推荐
  15. 走近Palantir
  16. 阿里云CDN产品介绍
  17. OpenStack 快速进阶教程
  18. 全球与中国苯乙烯-异戊二烯嵌段共聚物市场现状及未来发展趋势
  19. SpringCloud 学习笔记系列03--Hystrix熔断器
  20. matlab画足球,Matlab画足球

热门文章

  1. 1244:和为给定数
  2. SNS:95 后社交方式新主张
  3. 《新概念英语》英语的学习方法(完整版)
  4. 看Google收购Nest
  5. 建设商城网站需要注意事项_建设商城网站流程_OctShop
  6. Sequal Pro 连接docker容器中的mysql
  7. DDS信号发生器原理与经典DDS信号发生器设计方案
  8. 增加了网上商品比价搜索功能
  9. openssl 生成自签证书及查看证书细节
  10. 20、个人信息 - 小程序端开发 - 微擎小程序模块应用开发