我正在使用监视服务来监视目录并在新创建的文件上触发逻辑。我最近遇到的挑战之一是当需要处理大量文件并被快速复制到watch目录时触发溢出。
API说溢出:
文件系统可以比检索或处理事件更快地报告事件,并且实现可能会对可能累积的事件数量施加未指定的限制。如果实现有意丢弃事件,那么它会安排密钥的pollEvents方法返回事件类型为OVERFLOW的元素。
我的问题是,如何正确处理溢出,而不会丢失任何需要处理的事件?
我的watchservice代码如下:
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();
}
...
答案 0 :(得分: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;
}