NIO.2: Verzeichnisse im Dateisystem überwachen
0 Kommentar(e). Veröffentlicht von Christian Ullenboom am Donnerstag, Juli 30, 2009.Schreibt eine Anwendung etwa Log-Dateien in ein Verzeichnis, und ein anderes Programm soll dies erkennen, so gibt es bis Java 7 nur die Möglichkeit, laufend das Verzeichnis abzulaufen und nach Änderungen zu durchsuchen. Auch der Rückgriff auf native Zusatzbibliotheken wie http://jnotify.sourceforge.net/ ist eine Lösung. Seit Java 7 hat sich das geändert und Sun hat einen WatchService spendiert. Dazu ein Beispiel, um auf Änderungen im Verzeichnis C:/ zu reagieren.
com/tutego/insel/nio2/WatchServiceDemo.java, main()
WatchService watcher = FileSystems.getDefault().newWatchService();
Paths.get( "C:/" ).register( watcher, StandardWatchEventKind.ENTRY_CREATE,
StandardWatchEventKind.ENTRY_DELETE,
StandardWatchEventKind.ENTRY_MODIFY );
while ( true )
{
WatchKey key = watcher.take();
System.out.println( "Found" );
for ( WatchEvent<?> event : key.pollEvents() )
System.out.println( "Kind: " + event.kind() + ", Path: " + event.context() );
key.reset();
}
Ein Ablauf kann so aussehen:
Found
Kind: ENTRY_CREATE, Path: tutego - Kopie.log
Kind: ENTRY_MODIFY, Path: tutego - Kopie.log
Found
Kind: ENTRY_MODIFY, Path: tutego - Kopie.log
Found
Kind: ENTRY_DELETE, Path: tutego - Kopie.log
Kind: ENTRY_CREATE, Path: tutego2.log
Kind: ENTRY_MODIFY, Path: tutego2.log
Found
Kind: ENTRY_DELETE, Path: tutego2.log
Ein WatchService überwacht Änderungen an Watchable-Objekten. Path ist bisher die einzige Klasse, die die Schnittstelle Watchable implementiert. Grundsätzlich ist der Überwachungsdienst nicht an Dateien und Verzeichnissen gebunden, doch Sun hat WatchService und Watchable in das Paket java.nio.file gelegt. Es bleibt abzuwarten, ob Sun dieses API auch noch für andere Dinge nutzen wird.
Das Watchable meldet sich mit register() am WatchService an. Da es verschiede Ereignistypen gibt, ist register() mit einem Varargs-Parametertyp deklariert, der WatchEvent.Kind fordert: die Aufzählung StandardWatchEventKind deklariert drei mögliche WatchEvent.Kind-Typen.
Nach der Registrierung wird der Watcher nach den angefallen Ereignissen gefragt. Hier gibt es eine Variante mit take(), die blockierend wartet, oder poll(), die, falls kein Ereignisgruppe vorliegt, null liefert. Mit close() lässt sich der WachService beenden.
Das mit take() oder poll() entnommene Element ist vom Typ WatchKey. Ein WatchKey ist eine Art Gruppe aus einzelnen WatchEvents. Auf einem WatchKey-Objekt liefert pollEvents() genau diese List<WatchEvent<?>>. Vom WatchEvent erfragt kind() den WatchEvent.Kind, liefert also etwa StandardWatchEventKind.ENTRY_CREATE und context() das Objekt, auf das es sich bezog. Bei Dateisystemen dürfte context()immer ein Path liefert, aber der Rückgabetyp von context() ist mit T parametrisiert, was uns aber nicht hilft, denn key.pollEvents() liefert nur ein WatchEvent<?>, also ohne Typ. Hier zeigt sich, dass Wildcards in der Rückgabe nicht besonders hilfreich sind.
Labels: Insel

0 Antwort(en) auf ›NIO.2: Verzeichnisse im Dateisystem überwachen‹
Kommentar veröffentlichen