0

我正在使用“看门狗”api 来不断检查文件系统中文件夹中的更改。无论该文件夹中的文件发生什么变化,我都会将它们传递给一个特定的函数,该函数会为我传递的每个文件启动线程。

但是看门狗或任何其他文件系统观察者api(据我所知)会逐个文件通知用户,即当文件通过时,它们会通知用户。但我希望它一次通知我一大堆文件,以便我可以将该列表传递给我的函数并使用多线程。目前,当我使用“看门狗”时,它一次通知我一个文件,我只能将该文件传递给我的函数。我想一次传递许多文件以便能够进行多线程处理。

我想到的一个解决方案是:当您在文件夹中复制一堆文件时,操作系统会显示一个进度条。如果在进度条完成时可以通知我,那么这将是我的问题的完美解决方案。但我不知道这是否可能。

我也知道看门狗是一个轮询 API,用于监视文件系统的理想 API 是像 pyinotify 这样的中断驱动 API。但我没有找到任何中断驱动且跨平台的 API。iWatch 很好,但只适用于 linux,我想要适用于所有操作系统的东西。因此,如果您对任何其他 API 有任何建议,请告诉我。

谢谢。

4

1 回答 1

2

您可以生成一个从公共队列获取任务的工作线程池,而不是累积文件系统事件。然后,当文件系统事件发生时,看门狗线程可以将任务放入队列中。通过这种方式,工作线程可以在事件发生后立即开始工作。

例如,

import logging
import Queue
import threading
import time
import watchdog.observers as observers
import watchdog.events as events

logger = logging.getLogger(__name__)

SENTINEL = None

class MyEventHandler(events.FileSystemEventHandler):
    def on_any_event(self, event):
        super(MyEventHandler, self).on_any_event(event)            
        queue.put(event)
    def __init__(self, queue):
        self.queue = queue

def process(queue):
    while True:
        event = queue.get()
        logger.info(event)


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
                        format='[%(asctime)s %(threadName)s] %(message)s',
                        datefmt='%H:%M:%S')

    queue = Queue.Queue()
    num_workers = 4
    pool = [threading.Thread(target=process, args=(queue,)) for i in range(num_workers)]
    for t in pool:
        t.daemon = True
        t.start()

    event_handler = MyEventHandler(queue)
    observer = observers.Observer()
    observer.schedule(
        event_handler,
        path='/tmp/testdir',
        recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

跑步

% mkdir /tmp/testdir
% script.py

产生像这样的输出

[14:48:31 Thread-1] <FileCreatedEvent: src_path=/tmp/testdir/.#foo>
[14:48:32 Thread-2] <FileModifiedEvent: src_path=/tmp/testdir/foo>
[14:48:32 Thread-3] <FileModifiedEvent: src_path=/tmp/testdir/foo>
[14:48:32 Thread-4] <FileDeletedEvent: src_path=/tmp/testdir/.#foo>
[14:48:42 Thread-1] <FileDeletedEvent: src_path=/tmp/testdir/foo>
[14:48:47 Thread-2] <FileCreatedEvent: src_path=/tmp/testdir/.#bar>
[14:48:49 Thread-4] <FileCreatedEvent: src_path=/tmp/testdir/bar>
[14:48:49 Thread-4] <FileModifiedEvent: src_path=/tmp/testdir/bar>
[14:48:49 Thread-1] <FileDeletedEvent: src_path=/tmp/testdir/.#bar>
[14:48:54 Thread-2] <FileDeletedEvent: src_path=/tmp/testdir/bar>

Doug Hellman 编写了一套出色的教程(现已编辑成一本书),应该可以帮助您入门:

正如最后两个链接中讨论的那样,我实际上并没有最终使用多处理池或线程池,但无论如何您可能会发现它们很有用。

于 2014-10-04T18:55:41.650 回答