OS X上的Python中的监视程序库 - 不显示完整的事件路径

时间:2013-07-08 22:50:57

标签: python macos filesystems watchdog

我刚开始使用Mac上的Python Watchdog library,我正在做一些基本的测试,以确保事情按照我的预期运作。不幸的是,他们不是 - 我似乎只能获得包含注册事件的文件的文件夹的路径,而不是文件本身的路径。

下面是一个简单的测试程序(稍微修改一下Watchdog提供的示例),以便在注册事件时打印出事件类型,路径和时间。

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

class TestEventHandler(FileSystemEventHandler):

def on_any_event(self, event):
    print("event noticed: " + event.event_type + 
                 " on file " + event.src_path + " at " + time.asctime())

if __name__ == "__main__":
    event_handler = TestEventHandler()
    observer = Observer()
    observer.schedule(event_handler, path='~/test', recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

src_path变量应该包含发生事件的文件的路径。

但是,在我的测试中,当我修改文件时,src_path只打印包含文件的文件夹的路径,而不是文件本身的路径。例如,当我修改文件夹moon.txt中的文件europa时,程序将打印以下输出:

event noticed: modified on file ~/test/europa at Mon Jul  8 15:32:07 2013

为了获得修改文件的完整路径,我需要更改什么?

2 个答案:

答案 0 :(得分:3)

问题解决了。事实证明,OS X中的FSEvents仅返回文件修改事件的目录,让您自己扫描目录以找出修改的文件。 Watchdog文档中没有提到这一点,尽管在FSEvents文档中很容易找到它。

要获取文件的完整路径,我添加了以下代码片段(inspired by this StackOverflow thread)以查找目录中最近修改的文件,以便在event.src_path返回目录时使用。

if(event.is_directory):
    files_in_dir = [event.src_path+"/"+f for f in os.listdir(event.src_path)]
    mod_file_path = max(files_in_dir, key=os.path.getmtime)

mod_file_path包含修改文件的完整路径。

答案 1 :(得分:1)

感谢ekl提供您的解决方案。我偶然发现了同样的问题。但是,我曾经使用PatternMatchingEventHandler,这需要对您的解决方案进行少量更改:

    来自FileSystemEventHandler的
  • 子类
  • 创建一个属性pattern,您可以在其中存储模式匹配。这不像原始PatternMatchingEventHandler那样灵活,但应该足以满足大多数需求,如果你想扩展它,你也会得到这个想法。

以下是您必须在FileSystemEventHandler子类中添加的代码:

def __init__(self, pattern='*'):
    super(MidiEventHandler, self).__init__()
    self.pattern = pattern


def on_modified(self, event):
    super(MidiEventHandler, self).on_modified(event)

    if event.is_directory:
        files_in_dir = [event.src_path+"/"+f for f in os.listdir(event.src_path)]
        if len(files_in_dir) > 0:
            modifiedFilename = max(files_in_dir, key=os.path.getmtime)
        else:
            return
    else:
        modifiedFilename = event.src_path

    if fnmatch.fnmatch(os.path.basename(modifiedFilename), self.pattern):
        print "Modified MIDI file: %s" % modifiedFilename

我改变的另一件事是在文件列表上运行max()之前检查目录是否为空。 max()不适用于空列表。