Monitorear cambios en archivos de una carpeta
Cuando necesitemos desarrollar una aplicación que este pendiente de los cambios que ocurren en los archivos contenidos dentro de una carpeta como: modificación, eliminación o creación, la solución es utilizar la API Watch Service que nos permitirá recibir notificaciones de los cambios ocurridos dentro del directorio indicado.
Para monitorear las modificaciones en una carpeta haremos los siguientes pasos:
- Crear un objeto
WatchService
que será el encargado de observar los cambios en una o varias carpetas. - Registrar la carpeta y los cambios que deseamos monitorear, estos cambios están definidos en la clase
StandardWatchEventKinds
. - Crear un bucle en donde verificaremos si existe un evento en la cola.
- Obtener el objeto
WatchKey
que nos brinda información sobre el evento ocurrido. - Resetear el objeto
WatchKey
y continuar el bucle. - Para terminar el monitoreo usaremos el método
close()
.
El código de ejemplo:
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class Watcher {
public static void main(String[] args) {
try (WatchService ws = FileSystems.getDefault().newWatchService()) {
// carpeta que deseamos monitorear
Path dirToWatch = Paths.get("C:\\developer\\temp");
// eventos que deseamos que nos envien notificaciones
dirToWatch.register(ws, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
System.out.println("Watching " + dirToWatch + " for events.");
while (true) {
// obtener el key
WatchKey key = ws.take();
// procesar los eventos ocurridos
for (WatchEvent<?> event : key.pollEvents()) {
Kind<?> eventKind = event.kind();
if (eventKind == OVERFLOW) {
System.out.println("Event overflow occurred");
continue;
}
// obtener informacion del evento ocurrido
WatchEvent<Path> currEvent = (WatchEvent<Path>) event;
Path dirEntry = currEvent.context();
System.out.println(eventKind + " occurred on " + dirEntry);
}
// resetear el key
boolean isKeyValid = key.reset();
if (!isKeyValid) {
break;
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Programación con la API Watch Service
El objeto WatchService
es creado usando la clase FileSystems
:
WatchService ws = FileSystems.getDefault().newWatchService()
Luego obtenemos el Path
que representa la carpeta que deseamos monitorear y registramos los eventos que deseamos recibir, ellos son: ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE, los cuales indican los eventos de creación, modificación y eliminación de un archivo que se encuentre dentro de la carpeta indicada.
// carpeta que deseamos monitorear
Path dirToWatch = Paths.get("C:\\developer\\temp");
// eventos que deseamos que nos envien notificaciones
dirToWatch.register(ws, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
Creamos el bucle que nos permitirá obtener y procesar todos los eventos que se encuentren en la cola.
for (;;) {
// obtener el key
WatchKey key = watcher.take();
// procesar los eventos ocurridos
for (WatchEvent<?> event: key.pollEvents()) {
:
}
// resetear el key
boolean valid = key.reset();
if (!valid) {
break;
}
}
Finalmente procesamos cado uno de los eventos, verificamos si el evento es OVERFLOW esto indica si dicho evento a sido descartado o se ha perdido, en tal caso continuamos, en caso contrario podemos obtener el evento ocurrido e información del mismo, en nuestro ejemplo mostramos la carpeta que ha producido el mencionado evento.
for (WatchEvent<?> event : key.pollEvents()) {
Kind<?> eventKind = event.kind();
if (eventKind == OVERFLOW) {
System.out.println("Event overflow occurred");
continue;
}
// obtener informacion del evento ocurrido
WatchEvent<Path> currEvent = (WatchEvent<Path>) event;
Path dirEntry = currEvent.context();
System.out.println(eventKind + " occurred on " + dirEntry);
}
Si ejecutamos nuestra aplicación y hacemos los respectivos cambios en la carpeta indicada obtendremos la siguiente salida:
Como podemos ver si, agregamos, eliminamos o editamos un archivo en la carpeta establecida nuestra aplicación recibirá las notificaciones correspondientes.
No funciona cuando la carpeta es Montada (Remota) ...
ResponderEliminarhay que hacer algun ajuste???.
gracias
Monitorear una carpeta remota en un tema aparte.
EliminarHola, este ejemplo es mas optimo aplicarlo con Threads o asi como lo muestra en el ejemplo??
ResponderEliminarDepende del uso que tengas planeado, igual se puede aplicar de uno u otra forma.
Eliminar