python监控文件变化-----watchdog

前言

前些日子用了pyinotify来实现文件的监听,现在我们通过watchdog来实现下监听文件的变化。pyinotify依赖与Linux平台的inotify,watchdog对不同平台的事件都进行了封装。所以学好watchdog我们就不怕平台的切换导致模块不能使用了。

简单实例

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 = "自己目录地址"
    # 将使用内置的LoggingEventHandler
    event_handler = LoggingEventHandler()

    # 创建一个Observer
    observer = Observer()
    # 使用附加事件处理程序的观察者实例调度监视一些路径(观察者实例将不监视子目录, recursive:True则监听整个子目录)
    observer.schedule(event_handler, path, recursive=True)
    # 启动观察线程,等待它生成事件,而不会阻塞主线程
    observer.start()
    try:
        while True:
            time.sleep(1)
    finally:
        observer.stop()
        observer.join()

类介绍

events(watchdog.events.FileSystemEvent)

当受监视的文件系统发生更改时,不可变类型的文件系统将会被触发;所有FileSystemEvent对象都必须是不可变的,因此可以用作字典中的键或添加到集合中。
属性:

  1. event.event_type: 事件类型
  2. event.src_path: 触发该事件的文件或目录路径
  3. event.is_directory:该事件是否由一个目录触发

方法(事件):watchdog.events.FileSystemEvent为父类

  1. watchdog.events.FileDeletedEvent() : 文件被删除时触发该事件
  2. watchdog.events.DirDeletedEvent(): 目录被删除时触发该事件
  3. watchdog.events.FileCreatedEvent() : 文件被创建时触发该事件
  4. watchdog.events.DirCreatedEvent() : 目录被创建时触发该事件
  5. watchdog.events.FileModifiedEvent() : 文件被修改时触发该事件(修改文件内容、修改文件inode信息如权限和访问时间,都会触发该事件)
  6. watchdog.events.DirModifiedEvent() : 目录被修改时触发该事件
  7. watchdog.events.FileMovedEvent() : 文件被移动或重命名时触发该事件,因为涉及文件移动,所以除了event.src_path表示原路径,还有event.dest_path表示目的路径
  8. watchdog.events.DirMovedEvent() : 目录被移动或重命名时触发该事件,因为涉及文件移动,所以除了event.src_path表示原路径,还有event.dest_path表示目的路径

Event Handler( watchdog.events.FileSystemEventHandler)

事件处理器的基类,用于处理事件,用户需继承该类,并在子类中重写对应方法

实例方法:

  1. self.dispatch(event):接收到一个事件后,通过该方法来决定该event由下面哪个方法处理
  2. self.on_any_event(event): 捕获所有事件处理程序。任何事件发生都会首先执行该方法,该方法默认为空,dispatch()方法会先执行该方法,然后再把event分派给其他方法处理
  3. self.on_created(event): 在创建文件或目录时调用。处理DirCreatedEventFileCreatedEvent事件,子类需重写该方法
  4. self.on_deleted(event) : 删除文件或目录时调用。处理DirDeletedEventFileDeletedEvent事件,子类需重写该方法
  5. self.on_modified(event): 修改文件或目录时调用。处理DirModifiedEventFileModifiedEvent事件,子类需重写该方法
  6. self.on_moved(event): 在文件或目录被移动或重命名时调用。处理DirMovedEventFileMovedEvent事件,子类需重写该方法

事件处理类

1- watchdog.events.PatternMatchingEventHandler

检查触发事件的src_pathdest_path,是否与patterns指定的模式匹配,如果需要按模式匹配处理事件,则可以继承该类,不过需要自己实现on_moved()on_created()on_deleted()on_modified()这四个方法

from watchdog.events import PatternMatchingEventHandler, FileSystemEventHandler


class PatternMatchingEventHandler(FileSystemEventHandler):

    def __init__(self, patterns=None, ignore_patterns=None, ignore_directories=False, case_sensitive=False):
        """
        将给定的模式与与发生的事件关联的文件路径匹配
        :param patterns:允许匹配事件路径的模式
        :param ignore_patterns:忽略匹配事件路径的模式
        :param ignore_directories:如果为True,应该忽略目录;否则false
        :param case_sensitive:如果为True,路径名应区分大小写;否则false
        :return:
        """

2- watchdog.events.RegexMatchingEventHandler

通过正则表达式与与发生的事件关联的文件路径进行匹配。

from watchdog.events import FileSystemEventHandler


class RegexMatchingEventHandler(FileSystemEventHandler):

    def __init__(self, regexes=None, ignore_regexes=None,
                 ignore_directories=False, case_sensitive=False):
        """
        将给定的正则表达式与与发生的事件关联的文件路径进行匹配
        :param regexes:正则表达式允许匹配事件路径。
        :param ignore_regexes:正则表达式忽略匹配的事件路径
        :param ignore_directories:如果为true则忽略目录
        :param case_sensitive:如果为True,路径区分大小写
        """

3- watchdog.events.LoggingEventHandler

使用logging模块记录所有事件信息(如开始例子所示)

observers

BaseObserver:监控文件变化,触发对应的事件类,然后调用关联的事件处理类来处理事件

方法属性

  1. add_handler_for_watch:添加一个新的事件处理器到watch中,watch是ObservedWatch()类或其子类的实例
  2. emitters: 返回由此观察者创建的事件发射器。
  3. remove_handler_for_watch:从watch中移除一个事件处理器
  4. schedule: 计划监视路径,并调用给定事件处理程序中指定的适当方法以响应文件系统事件。
  5. unschedule: 移除一个watch及这个watch上的所有事件处理器
  6. unschedule_all: 移除所有watch及关联的事件处理器
  7. on_thread_stop: 等同于observer.unschedule_all()
  8. stop: 调用该方法来停止observer线程

添加多个事件处理器例子

import time
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, LoggingEventHandler


class ScriptEventHandler(FileSystemEventHandler):
    def __init__(self):
        FileSystemEventHandler.__init__(self)

    # 文件移动
    def on_moved(self, event):
        if event.is_directory:
            print("directory moved from {src_path} to {dest_path}".format(src_path=event.src_path,
                                                                          dest_path=event.dest_path))
        else:
            print(
                "file moved from {src_path} to {dest_path}".format(src_path=event.src_path, dest_path=event.dest_path))

    # 文件新建
    def on_created(self, event):
        if event.is_directory:
            print("directory created:{file_path}".format(file_path=event.src_path))
        else:
            print("file created:{file_path}".format(file_path=event.src_path))

    # 文件删除
    def on_deleted(self, event):
        if event.is_directory:
            print("directory deleted:{file_path}".format(file_path=event.src_path))
        else:
            print("file deleted:{file_path}".format(file_path=event.src_path))

    # 文件修改
    def on_modified(self, event):
        if event.is_directory:
            print("directory modified:{file_path}".format(file_path=event.src_path))
        else:
            print("file modified:{file_path}".format(file_path=event.src_path))


if __name__ == "__main__":
    event_handler1 = ScriptEventHandler()
    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)  # 为watch新添加一个event handler
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

 

参考链接

官方文档

基于python的文件监控watchdog

你可能感兴趣的:(python,工具,python,linux)