通过pyinotify实现文件的监控,包括监控文件是否传输完成

首先安装pyinofitypip install pyinotify

创建Event Processor

与linux下面的inotify事件机制类似,我们通过继承ProcessEvent来实现对inotify事件的重写,这里将事件名封装成process_事件名,例如IN_CREATE会经过Event Processor变成process_IN_CREATE。下面是所有的事件:

Inotify EventsDescription
IN_CREATEFile/directory created in watched directory
IN_OPENFile/directory opened in watched directory
IN_ACCESSFile accessed
IN_ATTRIBAttributes of file/directory changed (e.g. permissions, timestamp, etc.)
IN_CLOSE_NOWRITENon-writable file/directory closed
IN_DELETEFile/directory deleted from watched directory
IN_DELETE_SELFFile/directory being watched deleted
IN_IGNOREDFile/directory no longer watched, deleted, or unmounted filesystem
IN_MODIFYFile/directory modified
IN_MOVE_SELFFile/directory moved. Must monitor destination to know destination path
IN_MOVED_FROMFile/directory moved from one watched directory to another
IN_MOVED_TOSimilar to IN_MOVED_FROM except for outgoing file/directory
IN_Q_OVERFLOWEvent queue overflowed
IN_UNMOUNTFilesystem of watched file/directory unmounted from system

下面将通过一个简短的例子来展示:

import os
import pyinotify


class EventProcessor(pyinotify.ProcessEvent):
    _methods = ["IN_CREATE",
                "IN_OPEN",
                "IN_ACCESS",
                "IN_ATTRIB",
                "IN_CLOSE_NOWRITE",
                "IN_CLOSE_WRITE",
                "IN_DELETE",
                "IN_DELETE_SELF",
                "IN_IGNORED",
                "IN_MODIFY",
                "IN_MOVE_SELF",
                "IN_MOVED_FROM",
                "IN_MOVED_TO",
                "IN_Q_OVERFLOW",
                "IN_UNMOUNT",
                "default"]


def process_generator(cls, method):
    def _method_name(self, event):
        print("Method name: process_{}()\n"
              "Path name: {}\n"
              "Event Name: {}\n".format(method, event.pathname, event.maskname))

    _method_name.__name__ = "process_{}".format(method)
    setattr(cls, _method_name.__name__, _method_name)


for method in EventProcessor._methods:
    process_generator(EventProcessor, method)

watch_manager = pyinotify.WatchManager()
event_notifier = pyinotify.Notifier(watch_manager, EventProcessor())

watch_this = os.path.abspath("/home/vincent/software")
watch_manager.add_watch(watch_this, pyinotify.ALL_EVENTS)
event_notifier.loop()

这里我们可以看到,监控了一个文件夹/home/vincent/software,当往这个文件夹中复制一份文件时,将会打印出所有对应的事件。

Method name: process_IN_CREATE()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_CREATE

Method name: process_IN_OPEN()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_OPEN

Method name: process_IN_MODIFY()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_MODIFY

Method name: process_IN_MODIFY()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_MODIFY

Method name: process_IN_MODIFY()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_MODIFY

Method name: process_IN_CLOSE_WRITE()
Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh
Event Name: IN_CLOSE_WRITE

可以看出来,他会记录下文件操作的每一步,包括文件创建IN_CREATE,文件打开IN_OPEN,文件修改IN_MODIFY,文件关闭IN_CLOSE_WRITE

Non-Blocking Loop非阻塞方式

上面的loop()的方式会阻塞进程,在loop后面的代码将不会被执行,这里有三种解决办法:

Notifier with a timeout 使用超时

在构造notifier时,timeout参数告诉Notifier以特定的时间间隔获取通知。

event_notifier = pyinotify.Notifier(watch_manager, EventProcessor(), timeout=10)

当使用超时时,应用程序将不会自动获得文件系统更改通知。需要在不同的时间显式调用event_notifier.process_events()event_notifier.read_events()。也可以调用event_notifier.check_events()来检查是否有事件等待处理。

ThreadedNotifier不同线程

可以将程序放到另一个线程中,通过ThreadedNotifier而不是Notifier调用,然后通过event_notifier.start()启动

event_notifier = pyinotify.ThreadedNotifier(watch_manager, EventProcessor())

watch_this = os.path.abspath("notification_dir")
watch_manager.add_watch(watch_this, pyinotify.ALL_EVENTS)
event_notifier.start()

AsyncNotifier异步

可以通过异步实现:

event_notifier = pyinotify.AsyncNotifier(watch_manager, EventProcessor())

然后通过调用asyncore中的loop()函数实现:

import asyncore
asyncore.loop()

inotify的局限性也适用于pyinotify。例如,不监视递归目录;必须运行另一个inotify实例来跟踪子目录。尽管Python提供了一个方便的inotify接口,但与C实现的inotify相比,会导致性能下降。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python2.7可以使用第三方库pyinotify实现文件监控pyinotify是一个Linux内核提供的inotify机制的Python封装,可以在Python程序中监控文件系统事件。 以下是一个简单的示例代码,可以监控指定目录下的文件创建、删除和修改事件: ```python import pyinotify # 定义文件系统事件处理器 class EventHandler(pyinotify.ProcessEvent): def process_IN_CREATE(self, event): print("File created: %s" % event.pathname) def process_IN_DELETE(self, event): print("File deleted: %s" % event.pathname) def process_IN_MODIFY(self, event): print("File modified: %s" % event.pathname) # 创建inotify实例 wm = pyinotify.WatchManager() mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY # 创建文件系统事件处理器实例 handler = EventHandler() # 创建notifier实例,关联watch manager和event handler notifier = pyinotify.Notifier(wm, handler) # 添加监控目录 wm.add_watch('/path/to/directory', mask, rec=True) # 开始监控 notifier.loop() ``` 在上面的代码中,我们定义了一个EventHandler类来处理文件系统事件,它继承自pyinotify.ProcessEvent。在process_IN_CREATE、process_IN_DELETE和process_IN_MODIFY三个方法中,我们分别处理了文件创建、删除和修改事件。 然后,我们创建了一个WatchManager实例和一个事件掩码mask,并将其关联到handler实例。接着,我们添加了要监控的目录,并调用notifier.loop()方法开始监控。 当有文件被创建、删除或修改时,EventHandler类中对应的方法就会被调用,打印出相应的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值