微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WatchService:缺少事件

如何解决WatchService:缺少事件

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

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

解决方法

我有一个类似的实现,有一个等待文件的服务。从这个article

当 poll 或 take API 返回 WatchKey 实例时,如果不调用其重置 API,它将不会捕获更多事件

因此在 takereset 调用之间,您没有收到事件。 解决方案是获取事件(或来自事件的数据)并尽快调用重置。我使用线程池并处理 Runnable 实例中的每个事件。如果您想沿着线程路径走下去,请查看 java 的 ExecutorService 。但是,您需要确保长时间运行的进程调用的任何内容都是线程安全的。

没有理由不能抓取所有的事件信息,然后调用reset并在reset调用后同步处理事件。如果这样做,您可能应该捕获 OVERFLOW 事件,以便知道您何时错过了事件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。