简体   繁体   English

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

[英]python pyinotify to monitor the specified suffix files in a dir

I want to monitor a dir , and the dir has sub dirs and in subdir there are somes files with .md . 我想监视一个目录,并且该目录具有sub dirs,并且在subdir中有一些带有.md文件。 (maybe there are some other files, such as *.swp...) (也许还有其他一些文件,例如* .swp ...)

I only want to monitor the .md files, I have read the doc, and there is only a ExcludeFilter , and in the issue : https://github.com/seb-m/pyinotify/issues/31 says, only dir can be filter but not files. 我只想监视.md文件,我已经阅读了文档,并且只有ExcludeFilter ,并且在问题中: https : //github.com/seb-m/pyinotify/issues/31说,只有dir可以是过滤器,而不是文件。

Now what I do is to filter in process_* functions to check the event.name by fnmatch . 现在,我要做的是过滤process_*函数,以通过fnmatch检查event.name

So if I only want to monitor the specified suffix files, is there a better way? 因此,如果我只想监视指定的后缀文件,是否有更好的方法? Thanks. 谢谢。

This is the main code I have written: 这是我编写的主要代码:

!/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

I think you basically have the right idea, but that it could be implemented more easily. 我认为您基本上有正确的想法,但可以更轻松地实施。

The ProcessEvent class in the pyinotify module already has a hook you can use to filter the processing of events. pyinotify模块中的ProcessEvent类已经具有一个钩子,可用于过滤事件处理。 It's specified via an optional pevent keyword argument given on the call to the constructor and is saved in the instance's self.pevent attribute. 它是通过调用构造函数时指定的可选pevent关键字参数指定的,并保存在实例的self.pevent属性中。 The default value is None . 默认值为None It's value is used in the class' __call__() method as shown in the following snippet from the pyinotify.py source file: 它的值在类的__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)

So you could use it only allow events for files with certain suffixes (aka extensions) with something like this: 因此,您可以使用它仅允许具有某些后缀(也称为扩展名)的文件的事件,如下所示:

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)

There's nothing particularly wrong with your solution, but you want your inotify handler to be as fast as possible, so there are a few optimizations you can make. 解决方案没有什么特别的问题,但是您希望inotify处理程序尽可能快,因此可以进行一些优化。

You should move your match suffixes out of your function, so the compiler only builds them once: 您应该将匹配后缀移出函数,因此编译器仅将它们构建一次:

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

I made them a set so you can do a more efficient match: 我为他们设置了一个集合,以便您可以进行更有效的匹配:

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

I'm only presuming that os.path.splitext and a set search are faster than an iterative fnmatch , but this may not be true for your really small list of extensions - you should test it. 我只是假设os.path.splitext和set搜索比迭代fnmatch快,但是对于您的扩展名很少的情况可能并不正确-您应该对其进行测试。

(Note: I've mirrored your code above where you return False when you make a match, but I'm not convinced that's what you want - it is at the very least not very clear to someone reading your code) (注意:我已经将您的代码镜像到您在进行匹配时返回False的上方,但是我不确定这就是您想要的-至少对于阅读您的代码的人来说不是很清楚)

You can use the __call__ method of ProcessEvent to centralize the call to suffix_filter : 您可以使用ProcessEvent__call__方法集中对suffix_filter的调用:

class EventHandler(pyinotify.ProcessEvent):
    def __call__(self, event):
        if not suffix_filter(event.name):
            super(EventHandler, self).__call__(event)

    def process_IN_CREATE(self, event):
        print "Creating:", event.pathname

    def process_IN_DELETE(self, event):
        print "Removing:", event.pathname

    def process_IN_MODIFY(self, event):
        print "Modifying:", event.pathname

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM