在python中文件监控主要有两个库:pyinotify依赖于Linux平台的inotify,Linux平台推荐使用此模块,功能比watchdog强大且全面
、watchdog。
watchdog模块
主要有3个角色:observer、event_handler、被监控的文件夹。三者原本是独立的,主要通过observer.schedule
函数将三者串起来,observer不断检测调用平台依赖代码对监控文件夹进行变动检测,当发现改变时,通知event_handler处理。
watchdog的3个角色
- Observer
主要作用是当作启动和关闭监控程序,给予文件夹路径后,Observer会监控文件夹的变化并且反馈变化。
使用from watchdog.observers import Observer
命令导入。 - events
watchdog的动作模块,具体作用是根据Observer模块反馈的事件分配不一样的操作动作方法,然后程序再继承这个方法开始执行所需的代码。
使用from watchdog.events import *
命令导入。 - 监控文件夹路径
代码实例
# 本模块的功能:<检测文件或目录变化>
# 导入watchdog对应模块
from watchdog.observers import Observer
from watchdog.events import *
# 导入时间模块
import time
class FileEventHandler(FileSystemEventHandler):
# 初始化
def __init__(self):
FileSystemEventHandler.__init__(self)
# 移动目录或文件
def on_moved(self, event):
now=time.strftime("%Y-%m-%d %H:%M;%S",time.localtime())
if event.is_directory:
print(f"{now} 移动目录从{event.src_path}到{event.dest_path}")
else:
print(f"{now} 移动文件从{event.src_path}到{event.dest_path}")
# 创建目录或文件
def on_created(self, event):
now=time.strftime("%Y-%m-%d %H:%M;%S",time.localtime())
if event.is_directory:
print(f"{now} 创建目录{event.src_path}")
else:
print(f"{now} 创建文件{event.src_path}")
# 删除目录或文件
def on_deleted(self, event):
now=time.strftime("%Y-%m-%d %H:%M;%S",time.localtime())
if event.is_directory:
print("{now} 删除目录{0}".format(event.src_path))
else:
print("{now} 删除文件{0}".format(event.src_path))
# 修改目录或文件
def on_modified(self, event):
now=time.strftime("%Y-%m-%d %H:%M;%S",time.localtime())
if event.is_directory:
print("{now} 修改目录{0}".format(event.src_path))
else:
print("{now} 修改文件{0}".format(event.src_path))
if __name__ == "__main__":
# 实例化Observer对象
observer = Observer()
event_handler = FileEventHandler()
# 设置监听目录
dis_dir = "F:\迅雷下载"
observer.schedule(event_handler,dis_dir,recursive=True) # recursive=True,可以直接写True,表示递归子目录
print(f"监控目录 {dis_dir}")
observer.start()
# try:
# while True:
# # 设置监听频率(间隔周期时间)
# time.sleep(1)
# except KeyboardInterrupt:
# observer.stop()
observer.join()
pyinotify模块
依赖于Linux内核的inotify功能,inotify是一个事件驱动的通知器,其通知接口从内核空间到用户空间通过三个系统调用。
Notifier是pyinotify模块最重要的类,用来读取通知和处理事件,默认情况下,Notifier处理事件的方式是打印事件。
Notifier类在初始化时接受多个参数,但是只有WatchManager对象是必须传递的参数,WatchManager对象保存了需要监视的文件和目录,以及监视文件和目录的哪些事件,Notifier类根据WatchManager对象中的配置来决定如何处理事件。
#!/usr/bin/env python3
import pyinotify
# 创建WatchManager对象
wm = pyinotify.WatchManager()
# 添加要监控的目录,以及要监控的事件,这里ALL_EVENT表示所有事件
wm.add_watch('/tmp',pyinotify.ALL_EVENTS)
# 交给Notifier进行处理
notifier = pyinotify.Notifier(wm)
# 循环处理事件
notifier.loop()
事件标志
下面列举的是事件标志位,可以用'与'来关联监控多个事件,例如multi_event = pyinotify.IN_OPEN | pyinotify.IN_CLOSE_NOWRITE
- IN_ACCESS
被监控项目或者被监控目录中的文件被访问,比如一个文件被读取 - IN_MODIFY
被监控项目或者被监控目录中的文件被修改 - IN_ATTRIB
被监控项目或者被监控目录中的文件的属性被修改 - IN_CLOSE_WRITE
一个可写的文件或者目录被关闭 - IN_CLOSE_NOWRITE
一个只读的文件或者目录被关闭 - IN_OPEN
文件或者目录被打开 - IN_MOVED_FROM
被监控项目或者目录中的文件被移除监控区域 - IN_MOVED_TO
文件或目录被移入监控区域 - IN_MOVE_SELF
自移动,即一个可执行文件在执行时移动自己 - IN_CREATE
在所监控的目录中创建子目录或文件 - IN_DELETE
在所监控的目录中删除目录或文件 - IN_DELETE_SELF
自删除,即一个可执行文件在执行时删除自己 - IN_CLOSE
文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
- IN_MOVE
文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)
- IN_UNMOUNT
宿主文件系统被umount
事件处理
前面的例子,我们使用的都是默认的事件处理方式:打印在屏幕上,而很多情况下我们需要定制事件的处理方式,来实现特殊的功能。定制事件需要继承ProcessEvent类,针对需要处理的事件编写process_事件名(self,event)
函数即可
import pyinotify
# 监控多个事件:文件被打开或者只读文件被关闭
multi_event = pyinotify.IN_OPEN | pyinotify.IN_CLOSE_NOWRITE
# 创建WatchManager对象
wm = pyinotify.WatchManager()
# 定制化事件处理类,注意继承
class MyEventHandler(pyinotify.ProcessEvent):
# 必须为process_事件名称,event表示事件对象
def process_IN_OPEN(self,event):
# event.pathname 表示触发事件的文件路径
print('OPEN',event.pathname)
def process_IN_CLOSE_NOWRITE(self,event):
print('CLOSE_NOWRITE',event.pathname)
# 实例化我们定制化后的事件处理类
handler = MyEventHandler()
# 在notifier实例化时传入,notifier会自动执行
notifier = pyinotify.Notifier(wm,handler)
# 添加监控的目录及事件
wm.add_watch('/tmp',multi_event)
notifier.loop()