Java 7 NIO watchservice vs jpathwatch

Posted

技术标签:

【中文标题】Java 7 NIO watchservice vs jpathwatch【英文标题】: 【发布时间】:2013-10-09 00:37:51 【问题描述】:

我正在工作的项目一直在使用 Java 6 和 jpathwatch (.95),现在正在升级到 Java 7。目前在 Windows 7 和 2008 Server 上。我正在重构代码区域以使用新的 Java 7 NIO,并且相对简单——甚至使用 NIO.2 来替换 jpathwatch。但是,我们代码的文件监视区域开始未能通过单元测试。似乎 Java 7 NIO 不会接收到其他机器的 UNC 路径中的更改 -

\\otherMach\path\to\watch.  

为了测试,我实现了 Java NIO 教程站点 http://docs.oracle.com/javase/tutorial/essential/io/fileio.html 中的代码,然后在 jpathwwatch 导入而不是 Java NIO 导入中创建了一个重复的类交换。 jpathwatch 适用于 UNC 路径,但 Java NIO 不适用。它似乎注册甚至返回该位置的初始事件键:(示例输出)

INFO: Watching: \\otherMach\path\to\watch
DEBUG: Added: \\otherMach\path\to\watch
INFO: Got event key: sun.nio.fs.WindowsWatchService$WindowsWatchKey@1f26ecd2
INFO: event key for: \\otherMach\path\to\watch

但从不承认任何进一步的变化。

jpathwatch 注册并报告目录和文件事件(尽管它不会在注册后立即报告初始事件)。

INFO: Watching: \\otherMach\path\to\watch
DEBUG: Added: \\otherMach\path\to\watch
INFO: Got event key: name.pachler.nio.file.impl.WindowsPathWatchService$WatchRecord@79a7bd3b
INFO: event key for: \\otherMach\path\to\watch
INFO: EVENT RECEIVED: ENTRY_CREATE file/dir created - \\otherMach\path\to\watch\New folder
INFO: Got event key: name.pachler.nio.file.impl.WindowsPathWatchService$WatchRecord@79a7bd3b
INFO: event key for: \\otherMach\path\to\watch
INFO: EVENT RECEIVED: ENTRY_CREATE file/dir created - \\otherMach\path\to\watch\New Text Document.txt

尽管在 jpathwatch 讨论中看到不支持网络观看 - 请注意 Uwe Pachler 对 UNC 路径的回复 - http://sourceforge.net/p/jpathwatch/discussion/888207/thread/8ea778de/?limit=25#0037

有人看过 UNC 路径和 Java 7 NIO.2 吗?还有其他或更新的解决方案吗?

谢谢,

-mjash

【问题讨论】:

遗憾的是,我刚刚遇到了与 UNC 和 Java7 WatchService 相同的问题和行为。 【参考方案1】:

看起来这是 JDK 中的 bug,已在 JDK 1.7.0_u60 中修复。我刚刚尝试了 u71(一直在使用 u45)并验证它现在适用于我的整个 UNC。

【讨论】:

【参考方案2】:

如果您在 WatchEvent 上使用 Oracle 文档中的教程和示例,您可能在处理事件后错过了调用 key.reset()。我刚刚遇到了同样的问题:

    void processEvent()
    for(;;)
        WatchKey key;           
        try 
            key = this.watcher.take();
         catch (InterruptedException ex)
            return;
        

        for(WatchEvent<?> event: key.pollEvents())
            WatchEvent<Path> newevent = (WatchEvent<Path>)event;
            Path filepath = newevent.context();

        ... clipped ....
        

        boolean valid = key.reset();
        if(!valid)
            break;
        
    

【讨论】:

感谢 colson 的反馈,但我确实包含了 reset()。每个类都是相同的,但有各自的导入和特定差异。【参考方案3】:

虽然总体上没有关于 UNC 路径和远程文件系统的明确描述,但我发现了以下内容:

起初似乎可以注册一个 WatchKey,但 WatchKey 立即失效 (WatchKey.isValid())。

由于直接连接到FileSystem,因此无法将 WatchKey 注册到远程位置。

可能的解决方法:

1. 远程文件观察器

分享一个远程 jvm 的路径列表,让它将更改转发到您的机器。

2. 轮询

另一种解决方法是轮询器(仅在时间紧迫的情况下才可推荐)。 如果你经常轮询,这会导致大量的网络流量。

在注册到远程路径时获得异常或在When to Use and Not Use This API 部分中阅读该异常会很好。

【讨论】:

以上是关于Java 7 NIO watchservice vs jpathwatch的主要内容,如果未能解决你的问题,请参考以下文章

Java 7 WatchService 对其他人来说很慢吗?

WatchService 有时会触发 ENTRY_MODIFY 两次,有时会触发一次

JDK 之 NIO 2 WatchServiceWatchKey(监控文件变化)

借助JDK7中WatchService实现文件变更监听

WatchService 可能存在不能再window工作

Java目录事件