python pyinotify监视dir中指定的后缀文件

时间:2013-08-19 00:34:53

标签: python inotify pyinotify

我想要监视一个目录,而dir有子目录,而在子目录中有一些.md的文件。 (也许还有一些其他文件,例如* .swp ...)

我只想监控.md文件,我已经阅读了文档,而且只有ExcludeFilter,而在问题中:https://github.com/seb-m/pyinotify/issues/31说,只有dir可以过滤而不是文件

现在我要做的是过滤process_*个功能,按event.name检查fnmatch

因此,如果我只想监视指定的后缀文件,有没有更好的方法?感谢。

这是我写的主要代码:

!/usr/bin/env python                                                                                                                                
# -*- coding: utf-8 -*-

import pyinotify                                                                    
import fnmatch                                                                      

def suffix_filter(fn):                                                              
    suffixes = ["*.md", "*.markdown"]                                                                                                                
    for suffix in suffixes:                                                         
        if fnmatch.fnmatch(fn, suffix):                                             
            return False                                                            
    return True                                                                     

class EventHandler(pyinotify.ProcessEvent):                                         
    def process_IN_CREATE(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Creating:", event.pathname                                       

    def process_IN_DELETE(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Removing:", event.pathname                                       

    def process_IN_MODIFY(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Modifing:", event.pathname                                       

    def process_default(self, event):                                               
        print "Default:", event.pathname

3 个答案:

答案 0 :(得分:2)

我认为你基本上有正确的想法,但它可以更容易实现。

pyinotify 模块中的ProcessEvent类已经有一个可用于过滤事件处理的钩子。它是通过对构造函数的调用给出的可选pevent关键字参数指定的,并保存在实例的self.pevent属性中。默认值为None。它的值在类“__call__()方法中使用,如pyinotify.py源文件中的以下代码段所示:

def __call__(self, event):
    stop_chaining = False
    if self.pevent is not None:
        # By default methods return None so we set as guideline
        # that methods asking for stop chaining must explicitly
        # return non None or non False values, otherwise the default
        # behavior will be to accept chain call to the corresponding
        # local method.
        stop_chaining = self.pevent(event)
    if not stop_chaining:
        return _ProcessEvent.__call__(self, event)

所以你可以使用它只允许带有某些后缀(也就是扩展名)的文件的事件,如下所示:

SUFFIXES = {".md", ".markdown"}

def suffix_filter(event):
    # return True to stop processing of event (to "stop chaining")
    return os.path.splitext(event.name)[1] not in SUFFIXES

processevent = ProcessEvent(pevent=suffix_filter)

答案 1 :(得分:1)

您的解决方案没有什么特别的错误,但您希望您的inotify处理程序尽可能快,因此您可以进行一些优化。

您应该将匹配后缀移出函数,因此编译器只构建它们一次:

EXTS = set([".md", ".markdown"])

我让它们成为一套,这样你就可以进行更有效的比赛:

def suffix_filter(fn):
  ext = os.path.splitext(fn)[1]
  if ext in EXTS:
    return False
  return True

我只是假设os.path.splitext和集合搜索比迭代fnmatch更快,但对于你真正小的扩展列表可能不是这样 - 你应该测试它。

(注意:我在上面的代码中反映了你在匹配时返回False的代码,但我不相信这是你想要的 - 至少对于阅读你代码的人来说不是很清楚)< / p>

答案 2 :(得分:1)

您可以使用__call__的{​​{1}}方法将呼叫集中到ProcessEvent

suffix_filter