
WatchService jest mechanizmem wprowadzonym w Javie 7. Pozwala on na obserwowanie interesującego nas folderu. Jeśli przykładowo w obserwowanym folderze pojawi się nowy plik, otrzymamy zdarzenie informujące o tej zmianie. Jest to bardziej wydaje rozwiązanie niż każdorazowe odpytywanie systemu o to czy pojawiły się nowe pliki.
Tworzenie
Aby stworzyć nowy WatchService korzystamy z klasy FileSystems, która zwraca metody związane z aktualnym systemem operacyjnym. Klasa ta pozwala stworzyć WatchService zależny od aktualnego systemu operacyjnego:
WatchService watchService = FileSystems.getDefault().newWatchService();
Po utworzeniu usługi do nasłuchiwania pora na wskazanie miejsca, które chcemy obserwować.
Rejestrowanie
Każda klasa implementująca interfejs java.nio.file.Watchable otrzymała metodę WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events). Metoda ta pozwala zarejestrować stworzony przez nas WatchService. Podczas rejestracji musimy określić na jakie zdarzenia chcemy nasłuchiwać:
ENTRY_CREATE- nowy plik został stworzonyENTRY_DELETE- plik został usuniętyENTRY_MODIFY- plik został zmodyfikowanyOVERFLOW- informuje o tym, że utraciliśmy informację o zdarzeniu, nie ma potrzeby rejestrowania się na to zdarzenie, aby je otrzymywać
folder.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey
W odpowiedzi na zarejestrowanie WatchService otrzymaliśmy WatchKey. Klasa ta posiada metodę pollEvents(), która zwraca listę zdarzeń WatchEvent. Sam WatchKey może znajdować się w trzech stanach:
ready- gotowy do nasłuchiwania (jest w takim stanie zaraz po utworzeniu)signaled- znajduje się w tym stanie po zakolejkowaniu zdarzeń (już więcej nie nasłuchuje!)invalid- znajduje się w tym stanie gdy:WatchServicezostał zamknięty- folder przestał być dostępny
- została wywołana metoda
cancel
WatchEvent
Jest to zdarzenie, które wydarzyło się w zarejestrowanym folderze. WatchEvent dostarcza trzy metody:
count- ilość wystąpień danego zdarzeniacontext- nazwa pliku, dla którego zdarzenie wystąpiłokind- typ zdarzenia (uwaga, może być to typOVERFLOWnawet jeśli się na niego nie rejestrowaliśmy)
watchKey.pollEvents()
.forEach(x -> System.out.format(
“Context: %s Kind: %s Count: %d%n”, x.context(), x.kind().name(), x.count()));
Nasłuchujemy!
Poniżej znajduje się kompletny kod nasłuchujący na zmiany w folderze:
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(“dir/path/to/watch”);
WatchKey watchKey = path.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
while(true) {
watchKey.pollEvents()
.forEach(x -> System.out.format(
“Context: %s Kind: %s Count: %d%n”, x.context(), x.kind().name(), x.count()));
watchKey.reset();
}
Pojawiła się tu metoda reset, która do tej pory nie była opisana. Przypominam, iż WatchKey znajduje się w stanie ready do momentu zakolejkowania pierwszych zdarzeń. Potem nie nasłuchuje on już na nowe zdarzenia. Aby ponownie ustawić WatchKey w stan ready z signaled korzystamy z metody reset.