王旭阳个人博客

wxy

python监控系统文件变动

2024-01-14

前言

经常需要实时监控文件系统的变化,以便能够及时进行增量处理。在这方面,Python 提供了两个卓越的第三方开源工具:watchdogpyinotify

虽然可以通过轮询的方式监控文件系统,但这种方法效率低下,且不够优雅。因此,强烈推荐使用 watchdogpyinotify 进行监控。

watchdog

watchdog是一个Python库,用于监控文件系统事件。它可以监控文件和目录的创建、删除、修改等事件,并且跨平台兼容(Windows、macOS、Linux)。

以下是使用watchdog进行文件系统监控的基本步骤:

  1. 安装watchdog: 首先,你需要安装watchdog。这可以通过pip完成:

pip install watchdog
  1. 编写监控脚本: 使用watchdog的事件处理器和观察者来监控文件系统事件。

以下是一个简单的示例,它监控指定目录中的所有文件更改:

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time

class Watcher:
    DIRECTORY_TO_WATCH = "/path/to/my/directory"

    def __init__(self):
        self.observer = Observer()

    def run(self):
        event_handler = Handler()
        self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
        self.observer.start()
        try:
            while True:
                time.sleep(5)
        except:
            self.observer.stop()
            print("Observer Stopped")

        self.observer.join()


class Handler(FileSystemEventHandler):

    @staticmethod
    def on_any_event(event):
        if event.is_directory:
            return None

        elif event.event_type == 'created':
            # 文件创建
            print(f"Received created event - {event.src_path}.")
        
        elif event.event_type == 'modified':
            # 文件修改
            print(f"Received modified event - {event.src_path}.")

if __name__ == '__main__':
    w = Watcher()
    w.run()

在这个示例中,我们创建了一个Watcher类来初始化和运行监视器,以及一个Handler类来处理不同的文件系统事件。你可以根据需要修改DIRECTORY_TO_WATCH来监控不同的目录,并根据事件类型(如文件创建、修改)实现不同的逻辑。

请确保将"/path/to/my/directory"替换为你想监控的实际目录路径。

watchdog 事件

watchdog 事件 描述
FileSystemEventHandler 文件系统事件的基类
FileModifiedEvent 文件被修改时触发
FileCreatedEvent 创建文件时触发
FileDeletedEvent 删除文件时触发
FileMovedEvent 移动文件时触发
DirModifiedEvent 目录被修改时触发
DirCreatedEvent 创建目录时触发
DirDeletedEvent 删除目录时触发
DirMovedEvent 移动目录时触发

pyinotify

pyinotify 是一个 Python 库,用于监控文件系统事件,但它仅适用于 Linux 操作系统。它利用了 Linux 内核的 inotify 机制来监控文件和目录的变化,如创建、删除、修改等。

如果你正在使用 Linux 系统并且想使用 pyinotify 进行文件系统监控,可以按照以下步骤操作:

  1. 安装 pyinotify: 使用 pip 安装 pyinotify:

pip install pyinotify
  1. 编写监控脚本: 创建一个脚本来监控文件系统事件。以下是一个基本示例:

import pyinotify

class MyEventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        print(f"创建文件: {event.pathname}")

    def process_IN_DELETE(self, event):
        print(f"删除文件: {event.pathname}")

    def process_IN_MODIFY(self, event):
        print(f"修改文件: {event.pathname}")

def main():
    # 监控的路径
    path_to_watch = "/path/to/watch"

    # 设置事件掩码(监控文件创建、删除和修改)
    mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY

    wm = pyinotify.WatchManager()
    handler = MyEventHandler()
    notifier = pyinotify.Notifier(wm, handler)

    wdd = wm.add_watch(path_to_watch, mask, rec=True)

    notifier.loop()

if __name__ == "__main__":
    main()

在这个脚本中,我们定义了一个事件处理器 MyEventHandler,它继承自 pyinotify.ProcessEvent 并重写了几个方法来处理不同类型的事件(如文件创建、删除和修改)。然后在主函数中,我们创建了一个 pyinotify.WatchManager 实例,并添加了一个监控路径。

确保将 "/path/to/watch" 替换为你想监控的实际目录路径。

请注意,pyinotify 仅在 Linux 系统上工作。如果你需要跨平台解决方案,watchdog 是更好的选择。

pyinotify 事件

pyinotify 事件 描述
IN_ACCESS 文件被访问时触发
IN_MODIFY 文件被修改时触发
IN_ATTRIB 文件属性被修改时触发
IN_CLOSE_WRITE 可写文件被关闭时触发
IN_CLOSE_NOWRITE 不可写文件被关闭时触发
IN_OPEN 文件被打开时触发
IN_MOVED_FROM 文件被移出监控目录时触发
IN_MOVED_TO 文件被移入监控目录时触发
IN_CREATE 在监控目录中创建了新文件时触发
IN_DELETE 文件被删除时触发
IN_DELETE_SELF 监控的目录本身被删除时触发
IN_MOVE_SELF 监控的目录本身被移动时触发

二者区别

特性/库 pyinotify watchdog
平台兼容性 仅支持 Linux 跨平台(Linux, macOS, Windows)
底层机制 使用 Linux 的 inotify 接口 使用操作系统的本地文件监控机制
易用性 直接和简单 直接,但具有更多的配置选项
性能 高(直接使用内核级别的通知) 取决于操作系统和配置
用途 专注于 Linux 文件系统的监控 适用于需要跨平台文件监控的应用
安装 通过 pip 安装 通过 pip 安装
自定义处理 支持通过事件处理器定制处理 支持通过事件处理器定制处理
社区支持 有限 较广泛