1

I'm trying to evaluate a requirement in my current where I need to intercept file changes in a given directory and its sub-directories. The couple of tools which suited my requirement are jpathwatch and jnotify. jpathwatch works but doesn't have support for recursive directory watch. Jnotify seemed to address that limitation pretty well.

While evaluating jnotify, I observed a strange behavior. This is consistent in both linux and windows. Let me try to explain with an example. I've the following directory structure:


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

The jNotify is configured to listen to C:/Temp/File . Now, if I drop a file under "Dir" or "SubDir" folder , it captures the event as newly created. But, at the sametime, raises three file modification event. Here's the output when I add a new file Extraction.log in "SubDir" folder.


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

As you can see, there are 3 event on File modification. The application doesn't have any means to figure if its a modification or new file creation. So, it'll process the same file four times.

I'm using the sample code as shown in JNotify website.


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

Unfortunately, I can't use jdk 1.7 as we are stuck in 1.6.

I've seen few posts related to jNotify, I'll really appreciate if someone can provide pointers or any alternate solution to address this requirement.

Thanks

Shamik
  • 1,671
  • 11
  • 36
  • 64

1 Answers1

0

This is most probably not an issue with jNotify but because of the way the OS handles file creation. I have seen similar thing happening with the pynofity library in Python. You should handle this in your application code, like by delaying the trigger processing by few seconds, so that you can buffer any new events if any and then process only the latest event of a type.

Abhinav Sarkar
  • 23,534
  • 11
  • 81
  • 97
  • Thanks for your reply. As you mentioned, its probably an OS issue which raises multiple events on file creation or modification.But, I'm not sure how the buffering solution you proposed will work, specially when multiple files are being processed in a row. – Shamik Oct 09 '12 at 07:29