WatchService:缺少事件



我创建了一个小型Java应用程序,用于监视文件夹。它使用observer模式来通知不同的fileHandler。文件处理程序操作可能需要几秒钟的时间来处理文件。如果它一次只处理一个项目,那么一切都会很好。如果一个新文件在前一个文件完成之前到达,它将错过该事件,并且不会检测到新文件。解决这个问题的最佳模式是什么?我代码的某些部分。。。

WatchService watcher = FileSystems.getDefault().newWatchService();
List<Path> allPaths  = new ArrayList<Path>();
Path path = Paths.get("c:InPutFolder");
allPaths.add(path);

// Register all paths in the WatchService
Map<WatchKey, Path> allKeys = new HashMap<>();
for (Path path : allPaths) {
WatchKey key = path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
allKeys.put(key, path);
}
// Monitor the folders and listen for change notification.
while (true) {
WatchKey key = watcher.take();
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (ENTRY_CREATE.equals(kind)) {
Path path = allKeys.get(key);
// Store item in arrayList of objects 
Item item = new Item(path.toString(), event.context().toString());
ic.addItem(item);
notifyObservers(); // NOTIFY OBSERVERS & EXECUTE LONG PROCESS
} 
}
key.reset();
}

我有一个类似的实现,它有一个等待文件的服务。来自本文

当轮询或获取API返回WatchKey实例时,如果重置API而不调用,它将不会捕获更多事件

因此,在takereset调用之间,您不会接收到事件。解决方案是获取事件(或事件中的数据(并尽快调用reset。我使用线程池,并在Runnable实例中处理每个事件。如果您想走线程化的道路,请查看java的ExecutorService。但是,您需要确保无论您的长时间运行的进程调用什么都是线程安全的。

没有理由不能获取所有事件信息,然后调用reset并在reset调用后同步处理事件。如果你这样做了,你可能应该捕捉OVERFLOW事件,这样你就知道什么时候错过了事件。

相关内容

  • 没有找到相关文章

最新更新