官网:https://pythonhosted.org/watchdog/
需求:根据项目需求要写一个文件监控的程序,来学习一下这个库。
watchdog用来监控指定目录/文件的变化,如添加删除文件或目录、修改文件内容、重命名文件或目录等,每种变化都会产生一个事件,且有一个特定的事件类与之对应,然后再通过事件处理类来处理对应的事件,怎么样处理事件完全可以自定义,只需继承事件处理类的基类并重写对应实例方法。使用方法(根据官网给出的简单介绍常用的两个方法):
watchdog.observers.Observer
thread class.watchdog.events.FileSystemEventHandler
(or as in our case, we will use the built-in watchdog.events.LoggingEventHandler
, which already does).observer
instance attaching the event handler
.observer
thread and wait for it generate events without blocking our main thread.官网案例:
import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
if __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)
except KeyboardInterrupt:
observer.stop()
observer.join()
主要的内容都在events这个文件里面,包含了所有的可监听的事件.
使用案例:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from __future__ import print_function
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
WATCH_PATH = 'D:/test' # 监控目录
class FileMonitorHandler(FileSystemEventHandler):
def __init__(self, **kwargs):
super(FileMonitorHandler, self).__init__(**kwargs)
# 监控目录 目录下面以device_id为目录存放各自的图片
self._watch_path = WATCH_PATH
# 重写文件改变函数,文件改变都会触发文件夹变化
def on_modified(self, event):
if not event.is_directory: # 文件改变都会触发文件夹变化
file_path = event.src_path
print("文件改变: %s " % file_path)
def on_created(self, event):
print( '创建了文件夹', event.src_path)
def on_moved(self, event):
print("移动了文件",event.src_path)
def on_deleted(self, event):
print("删除了文件", event.src_path)
def on_any_event(self, event):
print("都会触发")
if __name__ == "__main__":
event_handler = FileMonitorHandler()
observer = Observer()
observer.schedule(event_handler, path=WATCH_PATH, recursive=True) # recursive递归的
observer.start()
observer.join()
watchdog.events.FileSystemEventHandler()
事件处理器的基类,用于处理事件,用户需继承该类,并在子类中重写对应方法。
类实例方法如下:
def dispatch(self, event):
"""Dispatches events to the appropriate methods.
:param event:
The event object representing the file system event.
:type event:
:class:`FileSystemEvent`
"""
self.on_any_event(event)
_method_map = {
EVENT_TYPE_MODIFIED: self.on_modified,
EVENT_TYPE_MOVED: self.on_moved,
EVENT_TYPE_CREATED: self.on_created,
EVENT_TYPE_DELETED: self.on_deleted,
}
event_type = event.event_type
_method_map[event_type](event)
self.on_created(event)
Called when a file or directory is created,也就是处理DirCreatedEvent和FileCreatedEvent事件,子类需重写该方法
self.on_deleted(event)
Called when a file or directory is deleted,也就是处理DirDeletedEvent和FileDeletedEvent事件,子类需重写该方法
self.on_modified(event)
Called when a file or directory is modified,也就是处理DirModifiedEvent和FileModifiedEvent事件,子类需重写该方法
watchdog.observers.Observer(timeout=1)
该类实现了监控文件变化,触发对应的事件类,然后调用关联的事件处理类来处理事件。该类其实是threading.Thread的子类,通过observer.start()使之运行在一个线程中,不会阻塞主进程运行,然后可以调用observer.stop()来停止该线程
实例属性及方法:
observer.schedule(event_handler, path, recursive=False)
监控指定路径path,该路径触发任何事件都会调用event_handler来处理,如果path是目录,则recursive=True则会递归监控该目录的所有变化。每一次调用schedule()对一个路径进行监控处理就叫做一个watch,schedule()方法会返回这个watch,接着可以对这个watch做其他操作,如为该watch增加多个event处理器等
注:内部由一个字典handlers来保存所有watch,watch的值是一个集合,包含对应此watch的所有event handler:
handlers = {
watch1: set(event_handler1, event_handler2),
watch2: set(event_handler),
}
observer.add_handler_for_watch(event_handler, watch)
添加一个新的事件处理器到watch中,watch是ObservedWatch()类或其子类的实例
observer.remove_handler_for_watch(event_handler, watch)
从watch中移除一个事件处理器
observer.unschedule(watch)
移除一个watch及这个watch上的所有事件处理器
observer.unschedule_all()
移除所有watch及关联的事件处理器
observer.on_thread_stop()
等同于observer.unschedule_all()
observer.stop()
调用该方法来停止observer线程