読者です 読者をやめる 読者になる 読者になる

JDK7 の WatchService を試す

Java

WatchService とは

JDK7でクロージャがやっぱり追加されることになったのはいいのですが、リリース時期が延びるそうで、NIO2を待たなければならないのは残念。ベータ版でNIO2を試してみよう。
WatchService とはファイルシステムに対する変更を監視できるサービス。自力でのポーリングなんかより簡単で効率よし。
β88(jdk-7-ea-bin-b88-windows-i586-08_apr_2010.exe)で試す。

WatchServiceのサンプル

WatchService のサンプルはこんな感じ。

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import static java.nio.file.StandardWatchEventKind.*;

public class WatchServiceSample {

    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("C:\\");
        WatchService watcher = FileSystems.getDefault().newWatchService();
        dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

        for (;;) {
            WatchKey watchKey = watcher.take();
            for (WatchEvent<?> event: key.pollEvents()) {
                if (event.kind() == OVERFLOW) continue;
                
                WatchEvent<Path> ev = cast(event);

                Path name = ev.context();
                Path child = dir.resolve(name);
                
                System.out.format("%s: %s\n", event.kind().name(), child);
            }
            watchKey.reset();
        }
    }

    @SuppressWarnings("unchecked")
    static <T> WatchEvent<T> cast(WatchEvent<?> event) {
        return (WatchEvent<T>)event;
    }
}

指定のディレクトリ(上記ではC:\)にファイルを作成し、編集し、削除すると、各ファイル操作に応じて以下のような出力が得られる。

ENTRY_CREATE: C:\hoge.txt
ENTRY_MODIFY: C:\hoge.txt
ENTRY_DELETE: C:\hoge.txt

簡単な説明

システムデフォルトの WatchService を取得。該当ディレクトリにモニターするイベントタイプと共に登録。

WatchService watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);


watcher の待ち行列に入ったキーを取得。

WatchKey watchKey = watcher.take();

take()はキーが取得できるまでブロックする。poll()系のメソッドではブロックしない。

その後、WatchEvent を取得して内容表示。

WatchService の利点

ファイルの変更通知は、通常ネイティブのサポートが有効となっているため、大量のファイルの変更監視などを行う場合に WatchService は非常に良くスケールします。