7

我正在使用监视服务来监视目录并在新创建的文件上触发逻辑。我最近遇到的挑战之一是当需要处理大量文件并且被复制到监视目录中的速度太快而无法处理时会触发溢出。

API说这个关于溢出:

文件系统报告事件的速度可能比检索或处理事件的速度更快,并且实现可能对其可能累积的事件数量施加未指定的限制。如果实现故意丢弃事件,那么它会安排键的 pollEvents 方法返回事件类型为 OVERFLOW 的元素。

我的问题是,我怎样才能正确处理溢出,而不会丢失任何需要处理的事件?

我的手表服务代码如下所示:

            Path myDir = Paths.get(srcDir);
            try(WatchService watcher = myDir.getFileSystem().newWatchService()){
                myDir.register(watcher, ENTRY_CREATE,ENTRY_MODIFY);
                int x = 0;
                for(;;){
                    x++;
                    WatchKey watchKey = watcher.take();
                    LOGGER.debug("Event # {}",x);
                    List<WatchEvent<?>> events = watchKey.pollEvents();
                    LOGGER.info("Events Size {}",events.size());
                    for (WatchEvent event : events) {
                        if(event.kind() == OVERFLOW){
                            LOGGER.error("The Maximum watchService events has been reached!");
                            System.exit(1); //I exit so I know there is a problem - but how should I handle this? 
                        }
                        if (event.kind() == ENTRY_CREATE) {
                            LOGGER.info("File created: " + event.context().toString());
                            LOGGER.info("Beginning Processing:" +event.context().toString());
                            ...business logic here...
                        }
                    }
                    watchKey.reset();
                }
          ...
4

1 回答 1

2

我在实践中从未见过溢出事件。它旨在通知您,您将需要重新处理您正在观看的任何目录。您无需退出程序,只需使用单线程 File.list() 调用爬取目录即可。我已经剪切并粘贴了我如何在下面处理它。这段代码...

1) 记录问题

2) 设置一个标志以触发目录重新处理,该目录重新处理爬取目录中的所有文件

3) 跳过此 WatchEvent 的其余处理

// log overflow events and trigger reprocess later.
if (kind == OVERFLOW) 
{
    logger.warn("File listener recieved an overflow event.  You should probably check into this");
    overflowTriggeredFlag = true;
    continue;
}
于 2013-07-29T15:21:53.153 回答