質問

I'm looking for a way to get a notification when a certain file is modified. I want to call a certain method when this happens, but in some cases I also want that the method is not called.

I tried the following:

class FileListener extends Thread {
    private Node n;
    private long timeStamp;

    public FileListener(Node n) {
        this.n = n;
        this.timeStamp = n.getFile().lastModified();
    }

    private boolean isModified() {
        long newStamp = n.getFile().lastModified();

        if (newStamp != timeStamp) {
            timeStamp = newStamp;
            return true;
        } else { 
            return false; 
    }

    public void run() {
        while(true) {
            if (isModified()) {
                n.setStatus(STATUS.MODIFIED);
            }
            try {
                Thread.sleep(1000);
            } catch(Exception e) {
                e.printStackTrace();
            }
    }
}

The Node class contains a reference to the file, a STATUS (enum) and a reference to the FileListener of that file. When the file is modified, I want the status to change to STATUS.MODIFIED. But, in some cases, the file where the Node refers to changes to a new File and I don't want it to automatically change the status to Modified. In that case I tried this:

n.listener.interrupt(); //interrupts the listener
n.setListener(null); //sets listener to null
n.setFile(someNewFile); //Change the file in the node
//Introduce a new listener, which will look at the new file.
n.setListener(new FileListener(n)); 
n.listener.start(); // start the thread of the new listener

But what I get is an Exception thrown by 'Thread.sleep(1000)', because the sleep was interrupted and when I check the status, it is still modified to STATUS.MODIFIED.

Am I doing something wrong?

役に立ちましたか?

解決

What about the watch service : http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html?

WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = ...;
try {
    WatchKey key = dir.register(watcher, ENTRY_MODIFY);
} catch (IOException x) {
    System.err.println(x);
}

And then:

for (;;) {
  //wait for key to be signaled
  WatchKey key;
  try {
    key = watcher.take();
  } catch (InterruptedException x) {
    return;
  }

for (WatchEvent<?> event: key.pollEvents()) {
  WatchEvent.Kind<?> kind = event.kind();
  if (kind == OVERFLOW) {
      continue;
  }
...
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top