1

我正在尝试评估当前需要拦截给定目录及其子目录中的文件更改的需求。适合我要求的两个工具是 jpathwatch 和 jnotify。jpathwatch 有效,但不支持递归目录监视。Jnotify 似乎很好地解决了这个限制。

在评估 jnotify 时,我观察到一个奇怪的行为。这在linux和windows中都是一致的。让我试着用一个例子来解释。我有以下目录结构:


C:
|--> Temp |
          | --> File |
                     | --> Dir |
                               | --> SubDir

jNotify 被配置为监听 C:/Temp/File 。现在,如果我将文件放在“Dir”或“SubDir”文件夹下,它会将事件捕获为新创建的。但是,同时,引发三个文件修改事件。这是我在“SubDir”文件夹中添加新文件 Extraction.log 时的输出。


created C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log

如您所见,文件修改有 3 个事件。该应用程序无法确定它是修改还是创建新文件。因此,它将处理同一个文件四次。

我正在使用 JNotify 网站中显示的示例代码。


package com.test.io;

import net.contentobjects.jnotify.JNotify;

public class JNotifyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        JNotifyTest jNotify = new JNotifyTest();
        try {
            jNotify.sample();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void sample() throws Exception {
        // path to watch

        String path = "C:\\Temp\\File\\";

        // watch mask, specify events you care about,
        // or JNotify.FILE_ANY for all events.
        int mask = JNotify.FILE_CREATED  | 
        JNotify.FILE_DELETED  | 
        JNotify.FILE_MODIFIED | 
        JNotify.FILE_RENAMED;

        // watch subtree?
        boolean watchSubtree = true;

        // add actual watch
        int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());

        // sleep a little, the application will exit if you
        // don't (watching is asynchronous), depending on your
        // application, this may not be required
        Thread.sleep(1000000);

        // to remove watch the watch
        boolean res = JNotify.removeWatch(watchID);
        if (!res) {
            // invalid watch ID specified.
        }
    }

    class Listener implements JNotifyListener {
        public void fileRenamed(int wd, String rootPath, String oldName,
                String newName) {
            System.out.println("renamed " + rootPath + oldName + " -> " + newName);
        }
        public void fileModified(int wd, String rootPath, String name) {
            System.out.println("modified " + rootPath + name);
        }
        public void fileDeleted(int wd, String rootPath, String name) {
            System.out.println("deleted " + rootPath + name);
        }
        public void fileCreated(int wd, String rootPath, String name) {
            System.out.println("created " + rootPath + name);
        }
    }
}

不幸的是,我无法使用 jdk 1.7,因为我们被困在 1.6 中。

我很少看到与 jNotify 相关的帖子,如果有人可以提供指针或任何替代解决方案来解决此要求,我将不胜感激。

谢谢

4

1 回答 1

0

这很可能不是 jNotify 的问题,而是因为操作系统处理文件创建的方式。pynofity我已经看到Python 中的库发生了类似的事情。您应该在应用程序代码中处理此问题,例如将触发器处理延迟几秒钟,以便您可以缓冲任何新事件(如果有),然后仅处理某个类型的最新事件。

于 2012-10-09T05:22:12.633 回答