如何正确处理watchservice中的pollEvents()溢出类型?

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();
                }
          ...

1
溢出意味着你已经失去了事件。说想要处理一个溢出却不失去事件是没有意义的。 - Peter Lawrey
如果我由于溢出而错过了事件,我的下一个事件队列仍然存在吗?如果有,我该如何获取下一组事件?文档还说明:“消费者可以将此事件用作触发器,以重新检查对象的状态。” @PeterLawrey - Robert H
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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接