Processing でファイル変更を監視する

表題の通り。

Java の WatchService を使うと指定したディレクトリに生じた変更をモニタリングできる。 具体的には、WatchService を起動し、監視したいフォルダを指定。その後、WatchKey というオブジェクトに WatchService のイベントを随時保存し、それに変更がないか、変更があった場合はどのようなものか、をチェックすればよい。

一番下の「参考」 に貼ったブログを基本的には元にしているが、Processing 表記にするため多少変更している。

以下、実際のコード:

import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

WatchService watchService;
File dir;
Path path;
WatchKey watchKey;

void setup() {
  try {
    watchService = FileSystems.getDefault().newWatchService();

    dir = new File("/Users/Ken/Desktop");
    path = dir.toPath();
    path.register(
      watchService, 
      ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY
      );
  }
  catch (IOException ioe) {
    ioe.printStackTrace();
  }
}

void draw() {
  try {
    while ((watchKey = watchService.take()) != null) {
      for (WatchEvent<?> event : watchKey.pollEvents()) {
        System.out.println("Event kind: " + event.kind()
          + ". File affected : " + event.context() + ".");
      }
      watchKey.reset();
    }
  }
  catch (InterruptedException ie) {
    ie.printStackTrace();
  }
}

ただ、これは現在非常にラグがある。予想されるのは、watchservice以外の代替があるのではないか、watchservice自体が遅い、などいろいろあるけれど、実質的には別スレッドで定期的にファイル構造を読めばいいだけなので、案外自分で一から書いた方が早いのかもしれない。
暇なときにきちんと見直したい。

参考
- A Guide To NIO2 WatchService | Baeldung