pyinotify asyncio监控文件和文件夹变化

你可能会问,为什么不用python的watchdog?因为watchdog用户可重写的实例方法就那么几个:

self.on_any_event(event)
# 任何事件发生都会首先执行该方法,该方法默认为空,dispatch()方法会先执行该方法,然后再把 event 分派给其他方法处理
self.on_moved(event)
# 处理 DirMovedEvent 和 FileMovedEvent 事件,默认为空
self.on_created(event)
# 处理 DirCreatedEvent 和 FileCreatedEvent 事件,默认为空
self.on_deleted(event)
# 处理 DirDeletedEvent 和 FileDeletedEvent 事件,默认为空
self.on_modified(event)
# 处理 DirModifiedEvent 和 FileModifiedEvent 事件,默认为空

它无法判断文件操作是否完成,你需要自己写其他逻辑来判断。关于watchdog在CSDN有篇很详尽的博文–WatchDog 使用经验总结,以上事件也转自那篇博文。

下面我们来说说pyinotify,Pyinotify依赖于Linux内核的功能—inotify(内核2.6.13合并),它支持的事件如下:

@cvar IN_ACCESS: File was accessed.
@type IN_ACCESS: int
@cvar IN_MODIFY: File was modified.
@type IN_MODIFY: int
@cvar IN_ATTRIB: Metadata changed.
@type IN_ATTRIB: int
@cvar IN_CLOSE_WRITE: Writtable file was closed.
@type IN_CLOSE_WRITE: int
@cvar IN_CLOSE_NOWRITE: Unwrittable file closed.
@type IN_CLOSE_NOWRITE: int
@cvar IN_OPEN: File was opened.
@type IN_OPEN: int
@cvar IN_MOVED_FROM: File was moved from X.
@type IN_MOVED_FROM: int
@cvar IN_MOVED_TO: File was moved to Y.
@type IN_MOVED_TO: int
@cvar IN_CREATE: Subfile was created.
@type IN_CREATE: int
@cvar IN_DELETE: Subfile was deleted.
@type IN_DELETE: int
@cvar IN_DELETE_SELF: Self (watched item itself) was deleted.
@type IN_DELETE_SELF: int
@cvar IN_MOVE_SELF: Self (watched item itself) was moved.
@type IN_MOVE_SELF: int
@cvar IN_UNMOUNT: Backing fs was unmounted.
@type IN_UNMOUNT: int
@cvar IN_Q_OVERFLOW: Event queued overflowed.
@type IN_Q_OVERFLOW: int
@cvar IN_IGNORED: File was ignored.
@type IN_IGNORED: int
@cvar IN_ONLYDIR: only watch the path if it is a directory (new
                  in kernel 2.6.15).
@type IN_ONLYDIR: int
@cvar IN_DONT_FOLLOW: don't follow a symlink (new in kernel 2.6.15).
                      IN_ONLYDIR we can make sure that we don't watch
                      the target of symlinks.
@type IN_DONT_FOLLOW: int
@cvar IN_EXCL_UNLINK: Events are not generated for children after they
                      have been unlinked from the watched directory.
                      (new in kernel 2.6.36).
@type IN_EXCL_UNLINK: int
@cvar IN_MASK_ADD: add to the mask of an already existing watch (new
                   in kernel 2.6.14).
@type IN_MASK_ADD: int
@cvar IN_ISDIR: Event occurred against dir.
@type IN_ISDIR: int
@cvar IN_ONESHOT: Only send event once.
@type IN_ONESHOT: int
@cvar ALL_EVENTS: Alias for considering all of the events.
@type ALL_EVENTS: int

如果你需要监控一个文件夹,它定期有文件上传,上传完成后需要对最新的文件进行操作,那么使用pyinotifyIN_CLOSE_WRITE事件就非常合适。
使用pyinotify的方法有如下几种:

  1. Using the Notifier class without timeout
    The corresponding tutorial file can be found here: tutorial_notifier.py
  2. Using the Notifier class with a timeout
  3. Using the ThreadedNotifier Class
    The corresponding tutorial file can be found here: tutorial_threadednotifier.py.
  4. Using the AsyncNotifier Class
    The corresponding tutorial file can be found here: tutorial_asyncnotifier.py.
  5. 由于python3.6之后,asyncore已经被asyncio 取代,所以有了这个诡异的官方例程:pyinotify/asyncio_notifier.py。里面完全没写各种事件怎么处理,文档也没有。

后来一番搜索,终于找到了这个Using pyinotify with python 3 asyncio,代码如下:

import pyinotify
import asyncio


class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        if not event.dir:
            print("Got new file: ", event.pathname)

wm = pyinotify.WatchManager()  # Watch Manager
mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE  # watched events

loop = asyncio.get_event_loop()

notifier = pyinotify.AsyncioNotifier(wm, loop, default_proc_fun=EventHandler())
wdd = wm.add_watch('.', mask, rec=True, auto_add=True)

try:
    loop.run_forever()
except:
    print('\nshutting down...')

loop.stop()
notifier.stop()

参考文献:

  1. python文件夹,文件监听工具(pyinotify,watchdog)
  2. pyinotify
  3. Tutorial · seb-m/pyinotify Wiki
  4. Using pyinotify with python 3 asyncio
  5. WatchDog 使用经验总结
发布了227 篇原创文章 · 获赞 148 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/toopoo/article/details/105175901