A partir de Java 7 contamos con la posibilidad de observar cambios en un directorio y de este modo supervisar determinados eventos tales como creación, modificación o eliminación ocurridos en alguna ruta de nuestro sistema operativo.
La clase específica para monitorear directorios a partir de Java 7 es WatchService.
¿Cómo observar cambios en un directorio?
A fin de indicar que deseamos monitorear un directorio en particular debemos utilizar la clase Path y solicitarle un “WatchService”
Path directoryToWatch = Paths.get(directory);
WatchService watchService = directoryToWatch.getFileSystem().newWatchService();
Trabajando con el servicio WatchService y registrando eventos
Una vez que obtenemos el servicio, registramos el evento que deseamos monitorear. Por ejemplo creación, eliminación y modificación de archivos dentro del directorio.
directoryToWatch.register(watchService, new WatchEvent.Kind[] {ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY});
Observando eventos
A partir de allí ya ‘tomamos’ el servicio obteniendo un token con los eventos que van sucediendo. El método “.take()” se quedará esperando que algo suceda en el directorio, para los eventos que hemos registrado.
WatchKey key = watchService.take();
Veamos esto más claramente con un ejemplo:
package watcher;
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
public class FileChangeWatcher {
public void doWath(String directory) throws IOException {
System.out.println("WatchService in " + directory);
// Obtenemos el directorio
Path directoryToWatch = Paths.get(directory);
if (directoryToWatch == null) {
throw new UnsupportedOperationException("Directory not found");
}
// Solicitamos el servicio WatchService
WatchService watchService = directoryToWatch.getFileSystem().newWatchService();
// Registramos los eventos que queremos monitorear
directoryToWatch.register(watchService, new WatchEvent.Kind[] {ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY});
System.out.println("Started WatchService in " + directory);
try {
// Esperamos que algo suceda con el directorio
WatchKey key = watchService.take();
// Algo ocurrio en el directorio para los eventos registrados
while (key != null) {
for (WatchEvent event : key.pollEvents()) {
String eventKind = event.kind().toString();
String file = event.context().toString();
System.out.println("Event : " + eventKind + " in File " + file);
}
// Volvemos a escuchar. Lo mantenemos en un loop para escuchar indefinidamente.
key.reset();
key = watchService.take();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
A fin de ejecutar este ejemplo, podemos crear un “main”
import watcher.FileChangeWatcher;
import java.io.IOException;
public class App {
public static void main(String[] args) throws IOException {
FileChangeWatcher fileChangeWatcher = new FileChangeWatcher();
fileChangeWatcher.doWath("C://developer//");
}
}
Si en la carpeta tuviera un archivo test.txt el cual abro y modifico, la salida sería la siguiente
Event : ENTRY_MODIFY in File test.txt
De este modo contamos con la posibilidad de observar cambios en un directario para los eventos que deseemos de forma muy simple.
Una alternativa a esto es utilizar Apache Commons IO que dispone de un File Monitor con el mismo proposito.