JNotifyを使うとファイルの作成、削除、変更などのイベントを監視することができます。
インストール
Mavenを使っている場合はpom.xmlに次のような行を追加します。
<dependencies>
<dependency>
<groupId>net.contentobjects.jnotify</groupId>
<artifactId>jnotify</artifactId>
<version>0.94</version>
</dependency>
</dependencies>
また、JNotifyはOSネイティブの機能を利用するので実行時にネイティブライブラリが必要となります。
JNotifyのプロジェクトページからパッケージをダウンロードし、適当なディレクトリに展開してください。
この記事では ./lib
以下にパッケージを展開したものとします。
lib
└── jnotify-lib-0.94
├── 64-bit\ Linux
│ └── libjnotify.so
├── CHANGELOG
├── README
├── epl.html
├── jnotify-0.94-src.zip
├── jnotify-0.94.jar
├── jnotify-native-linux-0.94-src.zip
├── jnotify-native-macosx-0.94-src.zip
├── jnotify-native-win32-0.94-src.zip
├── jnotify.dll
├── jnotify_64bit.dll
├── lgpl.txt
├── libjnotify.jnilib
└── libjnotify.so
実行時には ./lib/jnotify-lib-0.94
を -Djava.library.path
に指定します。
サンプルコード
次のコードはファイル作成、削除、変更、移動の各イベントを監視するサンプルです。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>hello</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hello</name>
<properties>
<java.version>1.8</java.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>net.contentobjects.jnotify</groupId>
<artifactId>jnotify</artifactId>
<version>0.94</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
com.example.Example
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/java/com/example/Example.java
package com.example;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyException;
import net.contentobjects.jnotify.JNotifyListener;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Example {
public static void main(String[] args) throws JNotifyException, InterruptedException {
int mask =JNotify.FILE_CREATED |
JNotify.FILE_DELETED |
JNotify.FILE_MODIFIED |
JNotify.FILE_RENAMED;
String path = Paths.get(".").toAbsolutePath().toString();
int watchId = JNotify.addWatch(path, mask, true, new JNotifyListener() {
@Override
public void fileCreated(int i, String s, String s1) {
Path p = Paths.get(s).resolve(s1).normalize();
System.out.println("fileCreated: " + p);
}
@Override
public void fileDeleted(int i, String s, String s1) {
Path p = Paths.get(s).resolve(s1).normalize();
System.out.println("fileDeleted: " + p);
}
@Override
public void fileModified(int i, String s, String s1) {
Path p = Paths.get(s).resolve(s1).normalize();
System.out.println("fileModified: " + p);
}
@Override
public void fileRenamed(int i, String s, String s1, String s2) {
Path p = Paths.get(s).resolve(s1).normalize();
Path p1 = Paths.get(s).resolve(s1).normalize();
System.out.println("fileRenamed: " + p + " -> " + p1);
}
});
Thread.sleep(100 * 1000);
JNotify.removeWatch(watchId);
}
}
動作確認
$ mvn clean package
$ java -Djava.library.path=./lib/jnotify-lib-0.94 -jar target/hello-1.0.0-SNAPSHOT-jar-with-dependencies.jar
次の一連のコマンドを打ってみます。
$ echo hello > a.txt
$ echo hello >> a.txt
$ mv a.txt b.txt
$ rm b.txt
すると以下のような出力が確認できます。
fileCreated: /tmp/jnotify-example/a.txt
fileModified: /tmp/jnotify-example/a.txt
fileRenamed: /tmp/jnotify-example/a.txt -> /tmp/jnotify-example/a.txt
fileDeleted: /tmp/jnotify-example/b.txt
注意点
使用しているOSによって制限があります。
例えばMacではイベントの順番が前後したり、処理によってはイベントが失われたりといったことが発生することに留意する必要があります。