4

I would like to know how to efficiently implement filesystem changes in java? Say I got a file in a folder and modify that file. I would like to be notified by java about this change as soon as possible(no frequently polling if possible.).

Because I think I could call java.io.file.lastModified every few seconds but I don't like the sound of that solution at all.

alfred@alfred-laptop:~/testje$ java -version
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Server VM (build 16.0-b13, mixed mode)
tshepang
  • 12,111
  • 21
  • 91
  • 136
Alfred
  • 60,935
  • 33
  • 147
  • 186

4 Answers4

8

Take a look at JNotify, which performs this type of monitoring.

Java 7 will have some more advanced APIs (WatchService) for this sort of work which will eliminate polling on the OSes that support this.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • 1
    IIRC, JNotify requires OS specific DLLs. While likely not as performant (yeah, not yet a real word), JPoller provides a pure Java implementation. – Kaleb Pederson Mar 15 '10 at 22:39
  • So it is always a little hack I guess until using Java7 because I think Jpoller polls like crazy. JNotify isn't native.. – Alfred Mar 15 '10 at 23:02
  • Not quite sure what you mean by JNotify not being native. It does require OS-specific DLLs/libraries. – Brian Agnew Mar 15 '10 at 23:04
  • I am going to look closer at JNotify, but from what I read so far from JNofity is that it uses system specific solution. I hoped I missed something somewhere and just put a single jar in my classpath(in netbeans). Next call a function with a callback or something and get notified. – Alfred Mar 15 '10 at 23:33
  • 2
    Actually JNotify only makes calls to OS specific libraries for Win, OS X and Linux. It does not support other OSes and has no mechanism for polling. The Java 7 WatchService is basically the same as JNotify, but will fall back on polling if there is no filesystem-native watching facility to be used. – Jono Apr 28 '11 at 15:03
1

There is an Apache package that does file system monitoring: commons.io.monitor.

Documentation

An example

From what I can tell, you will still need to poll albeit you have control over the frequency.

Marko Galesic
  • 472
  • 5
  • 17
1

I doubt that there is a pure java way to do this. Operating systems offer APIs to monitor file system a activity. You will probably need to call those APIs.

Jim Blizard
  • 4,255
  • 28
  • 37
  • I have not looked at it at all but think it is actually part of what they address in the new file system APIs in Java7. At the end of the day it will of course need support from the file system or OS itself. – Fredrik Mar 15 '10 at 22:36
1

Use JNotify, All you need to do is add jnotify.jar in buildpath and put two dll files i.e jnotify.dll jnotify_64bit.dll and inside lib of jdk. A demo program is

package jnotify;

import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;

public class MyJNotify {
  public void sample() throws Exception {
    String path = "Any Folder location here which you want to monitor";
    System.out.println(path);
    int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED
            | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
    boolean watchSubtree = true;
    int watchID = JNotify
            .addWatch(path, mask, watchSubtree, new Listener());
    Thread.sleep(1000000);
    boolean res = JNotify.removeWatch(watchID);
    if (!res) {
        System.out.println("Invalid");
    }
}

class Listener implements JNotifyListener {
    public void fileRenamed(int wd, String rootPath, String oldName,
            String newName) {
        print("renamed " + rootPath + " : " + oldName + " -> " + newName);
    }

    public void fileModified(int wd, String rootPath, String name) {
        print("modified " + rootPath + " : " + name);
    }

    public void fileDeleted(int wd, String rootPath, String name) {
        print("deleted " + rootPath + " : " + name);
    }

    public void fileCreated(int wd, String rootPath, String name) {
        print("created " + rootPath + " : " + name);
    }

    void print(String msg) {
        System.err.println(msg);
    }
}
public static void main(String[] args) {
    try {
        new MyJNotify().sample();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211