Java 7 NIO 的监视服务与 jpathwatch 相比如何?

8

我正在参与的项目一直使用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时出现了相同的问题和行为。 - NBW
3个回答

2

看起来这是JDK中的一个漏洞,在JDK 1.7.0_u60中已经修复。我刚刚尝试了u71(之前使用的是u45),并验证它现在可以跨UNC正常工作。


0

虽然关于UNC路径和远程文件系统没有明确的描述,但我找到了以下信息:

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

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

可能的解决方法:

1. 远程文件监视器

共享要监视的路径列表到远程jvm,并让它将更改转发到您的计算机。

2. 轮询

另一个解决方法是轮询(仅在不需要时间临界性时推荐)。
如果您不断轮询,这将导致大量的网络流量。

很好的解决方法是,在注册到远程路径时获得异常,或者至少在“何时使用和不使用此API”部分中阅读相关信息。


0
如果您正在使用Oracle文档中关于WatchEvent的教程和示例,您可能会忽略在处理事件后调用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()。每个类都是相同的,只是针对各自的导入和特定差异。 - mjash

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