Als letztes in der Java 7 NIO.2 Reihe möchte ich eine neue Möglichkeit vorstellen, wie man Dateiänderungen bzw Verzeichnisänderungen überwachen kann. Bisher war dies nur über Polling möglich. Man hat den Timestamp der Datei/des Verzeichnisses überwacht, das CRC verglichen oder ähnliches. Neu ist nun ein Service der einem diese Arbeit abnimmt:
Der neue WatchService dient dazu Objete die das Watchable Interface implementieren zu überwachen. Die neue Path Klasse ist bisher das einzige solche Objekt, doch ist der WatchService somit offen für eigene Implementierungen.
Am WatchService registrieren sich Watchable Objekte zur Überwachung mittels der register() Methode
WatchService watcher = FileSystems.getDefault().newWatchService(); Path p = new Path("/home/"); WatchKey key = p.register(watcher, ENTRY_CREATE);
dabei hat man die Möglichkeit die Events auf die geachtet werden soll per varargs Parameter zu deklarieren und kann aus folgenden wählen:
- StandardWatchEventKinds.ENTRY_CREATE
- StandardWatchEventKinds.ENTRY_MODIFY
- StandardWatchEventKinds.ENTRY_DELETE
z.B. um alle arten zu überwachen
WatchKey key = p.register(watcher, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
Nun kann man auf zwei Arten auf das Ergebnis des WatchServices zugreifen: take() oder poll()
take() – arbeitet blockierend und wartet darauf dass ein Event geworfen wird
poll() – liest direkt aus ob ein Event vorhanden ist. Findet der Aufruf kein solches liefert es null zurück. Es ist somit nicht blockierend.
Die beiden Methoden zum Abfragen nach Events liefern bei einem Treffer jeweils ein Ojekt vom Typ WatchKey zurück. Dieser kann einen oder mehrere WatchEvents beinhalten die man mittels pollEvents() Methode als List abrufen kann. Die Art des einzelnen WatchEvent kann mittels kind() Methode erfragt werden, während context() das auslösende Objekt zurückliefert. Im Falle eines überwachten Paths sollte hier stehts ein weiterer Path zurückgegeben werden.
while(true){ WatchKey key = watcher.take(); for(WatchEvent event : key.pollEvents()){ if(event.kind() = ENTRY_CREATE){ Path result = (Path)event.context(); System.out.println(result.getName()); } } key.reset(); }
Das WatchService implementiert Closable und AutoClosable und ist somit mit close() wieder schließbar bzw. erspart man sich das im neuen TryCatchblock.
key.reset(); ist notwendig um den Thread wieder freizugeben, denn der WatchService ist während des ganzen Aufrufes blockiert.
Happy NIOing :)
Schreibe einen Kommentar