1

我在 Java OSGi 服务中使用 Apache JCI 的 FAM (FileAlterationMonitor) 来监视和处理文件系统中的更改。一切似乎都运行良好,除了每当我启动服务(它使用下面的代码启动 FAM)时,FAM 都会获取目录中存在的所有更改。

目前我正在看 /tmp /tmp 包含一个子树:/tmp/foo/bar/cat/dog

每次我启动服务并启动 FAM 时,它都会报告 DirectoryCreate 事件:

/tmp/foo
/tmp/foo/bar
/tmp/foo/bar/cat
/tmp/foo/bar/cat/dog

即使没有对该子树的任何部分进行任何更改。

服务激活时运行的代码:

File watchFolder = new File("/tmp"); 
watchFolder.mkdirs();

fam = new FilesystemAlterationMonitor();
fam.setInterval(1000);
fam.addListener(watchFolder, listener);
fam.start();
// I've already tried adding:
listener.waitForFirstCheck();

监听器示例:

private FileChangeListener listener = new FileChangeListener() {
    public void onDirectoryChange(File pDir) { System.out.println(pDir.getAbsolutePath()); }
    public void onDirectoryCreate(File pDir) { System.out.println(pDir.getAbsolutePath()); }
    ...
}
4

2 回答 2

1

是的,这是 JCI 的一个非常烦人的特性。当监控开始时,它会通过调用来通知你它找到的所有文件和目录onXxxCreate()。我认为您有以下选择

  • 开始监控后,在您的回调实现中等待一段时间(几秒钟),FileChangeListener然后再实际处理来自 JCI 的事件。这就是我在一个项目中所做的,它工作得很好,尽管您可能会错过在“宽限期”内发生的实际文件创建
  • 获取 JCI 的源并修改它们以使用两个新的事件方法onDirectoryFound(File),并且onFileFound(File)仅在启动监视时找到文件和目录时才会触发
  • 看看java.nio.file.WatchServiceJava 7 附带的。IMO 是最好的选择,因为它在内部使用本机方法来通知操作系统的更改,而不是启动线程并定期检查。使用 JCI,您可能会延迟几秒钟,直到更改传播到您的回调
于 2011-12-23T11:07:42.687 回答
0

忘记 WatchService。它不直观,并且在尝试查看它是否可以检测到它正在监视的文件夹被删除或更改时存在问题。我会远离它。我曾与 Watcher 合作过,但更喜欢 Apache IO。我相信骆驼也使用它。

于 2014-11-26T19:28:28.730 回答