WatchService: tiedostomuutosten valvonta
Rekisteröi WatchService havaitsemaan tiedostojen luonti-, muokkaus- ja poistotapahtumat reaaliajassa.
WatchService: tiedostomuutosten valvonta on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mikä on WatchService?
WatchService valvoo hakemistoa tiedostojärjestelmän tapahtumien varalta: luonti, muokkaus ja poisto. Se käyttää käyttöjärjestelmätason ilmoituksia (Linuxissa inotify, macOS:ssä FSEvents) — paljon tehokkaampaa kuin jatkuva kysely.
import java.nio.file.*;
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Path.of("/home/user/watched");
dir.register(watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE
);
System.out.println("Watching: " + dir);Tapahtumien kysely
Kutsukaa watcher.take()-metodia odottamaan estävästi, kunnes tapahtuma ilmenee, ja käsitelkää sitten tapahtumat:
while (true) {
WatchKey key;
try {
key = watcher.take(); // blocks until events arrive
} catch (InterruptedException e) {
break;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
Path changed = ((WatchEvent<Path>) event).context();
System.out.println(kind.name() + ": " + changed);
}
key.reset(); // must reset to receive further events
}Estämätön kysely
Käyttäkää watcher.poll()-metodia estämättömiin tarkistuksiin tai poll(timeout, unit)-metodia ajastettuun odotukseen:
// Non-blocking — returns null if no events
WatchKey key = watcher.poll();
if (key != null) {
// process events
key.reset();
}
// Wait up to 5 seconds:
WatchKey key2 = watcher.poll(5, java.util.concurrent.TimeUnit.SECONDS);
if (key2 != null) {
// process events
key2.reset();
}OVERFLOW-tapahtuma
Jos tapahtumia kertyy nopeammin kuin sovellus käsittelee niitä, OVERFLOW-tapahtuma ilmoittaa joidenkin tapahtumien kadonneen. Käsitelkää tilanne hallitusti:
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
System.out.println("OVERFLOW: some events missed, rescanning directory");
// rescan dir to find current state
continue;
}
// process normal events
}Täydellinen toimiva esimerkki
Täydellinen tiedostojen valvontaohjelma, joka suoritetaan taustasäikeessä:
class FileWatcher implements Runnable {
private final WatchService watcher;
FileWatcher(Path dir) throws IOException {
watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
WatchKey key = watcher.take();
for (WatchEvent<?> e : key.pollEvents())
System.out.println(e.kind() + ": " + e.context());
key.reset();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}Useiden hakemistojen valvonta
Rekisteröikää useita hakemistoja samaan WatchServiceen. Tunnistakaa palautetun WatchKey-avaimen avulla, mistä hakemistosta tapahtuma on peräisin:
Map<WatchKey, Path> keyMap = new HashMap<>();
for (Path dir : List.of(Path.of("/logs"), Path.of("/config"))) {
WatchKey key = dir.register(watcher,
StandardWatchEventKinds.ENTRY_MODIFY);
keyMap.put(key, dir);
}
WatchKey key = watcher.take();
Path dir = keyMap.get(key);
System.out.println("Changed in: " + dir);Täyden polun selvittäminen
Tapahtuman context() palauttaa vain tiedostonimen, ei täydellistä polkua. Selvittäkää polku valvotun hakemiston perusteella:
WatchEvent<Path> pathEvent = (WatchEvent<Path>) event;
Path filename = pathEvent.context();
Path fullPath = watchedDir.resolve(filename);
System.out.println("Full path: " + fullPath);Hakemistojen rekursiivinen valvonta
WatchService valvoo vain rekisteröityä hakemistoa, ei sen alihakemistoja. Käykää hakemistopuu läpi ja rekisteröikää jokainen alihakemisto rekursiivista valvontaa varten:
WatchService watcher = FileSystems.getDefault().newWatchService();
Path root = Path.of("/project");
try (var stream = Files.walk(root)) {
stream.filter(Files::isDirectory)
.forEach(dir -> {
try { dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
} catch (IOException e) { throw new RuntimeException(e); }
});
}Resurssien vapauttaminen
Sulkekaa WatchService aina, kun olette valmiit, jotta käyttöjärjestelmän resurssit vapautuvat:
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
Path dir = Path.of("/tmp/watch");
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey key = watcher.poll(10, java.util.concurrent.TimeUnit.SECONDS);
if (key != null) {
key.pollEvents().forEach(e -> System.out.println(e.context()));
key.reset();
}
} // watcher.close() called automaticallyKäytännön käyttötapaus: asetusten hot reload
Käyttäkää WatchServiceä asetusten lataamiseen uudelleen, kun tiedosto muuttuu:
class ConfigWatcher {
private volatile Map<String, String> config = new HashMap<>();
void loadConfig(Path file) throws IOException {
config = Files.readAllLines(file).stream()
.filter(l -> l.contains("="))
.collect(Collectors.toMap(
l -> l.split("=")[0].trim(),
l -> l.split("=")[1].trim(),
(a,b) -> b
));
}
// Call loadConfig again on ENTRY_MODIFY event
}WatchServicen rajoitukset
Tärkeät rajoitukset:
- Valvoo vain hakemistoja, ei yksittäisiä tiedostoja
- Ei ole oletusarvoisesti rekursiivinen — rekisteröikää jokainen alihakemisto manuaalisesti
- macOS:ssä käyttää sisäisesti kyselyä (reagoi hitaammin kuin Linuxin inotify)
- Saattaa ohittaa nopeasti peräkkäisten muutosten sarjoja (OVERFLOW)
- WatchKey muuttuu kelpaamattomaksi, jos valvottu hakemisto poistetaan
Pikatarkistus
Mitä on kutsuttava WatchKey-avaimen tapahtumien käsittelyn jälkeen, ennen kuin WatchService toimittaa kyseiselle avaimelle lisää tapahtumia?
Kertaus: WatchService
Tärkeimmät asiat:
- Rekisteröikää hakemistot ENTRY_CREATE-, ENTRY_MODIFY- ja ENTRY_DELETE-tapahtumille
- take() estää säikeen; poll() on estämätön; poll(timeout, unit) soveltuu ajastettuun odotukseen
- Kutsukaa aina key.reset() tapahtumien käsittelyn jälkeen
- context() palauttaa vain tiedostonimen — selvittäkää täydellinen polku valvotun hakemiston perusteella
- Sulkekaa WatchService try-with-resources-rakenteella
- Rekursiivinen valvonta edellyttää jokaisen alihakemiston rekisteröintiä
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”WatchService: tiedostomuutosten valvonta” ilmainen?
Kyllä – oppitunnin ”WatchService: tiedostomuutosten valvonta” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”WatchService: tiedostomuutosten valvonta”?
Rekisteröi WatchService havaitsemaan tiedostojen luonti-, muokkaus- ja poistotapahtumat reaaliajassa. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”WatchService: tiedostomuutosten valvonta”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Path: tiedostojen sijaintien esittäminen
- Files-apuohjelma: lue, kirjoita, kopioi ja siirrä
- Hakemistopuiden läpikäynti Files.walk-metodilla
- WatchService: tiedostomuutosten valvonta