Observar cambios en directorios con Java

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.

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también