WatchService: overvåke filendringer
Registrer en WatchService for å oppdage hendelser for filoppretting, endring og sletting i sanntid.
WatchService: overvåke filendringer er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva er WatchService?
WatchService overvåker en katalog for hendelser i filsystemet: oppretting, endring og sletting. Den bruker varsler på operativsystemnivå (inotify på Linux, FSEvents på macOS) — mye mer effektivt enn polling.
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);Polling etter hendelser
Kall watcher.take() for å blokkere til en hendelse oppstår, og behandle deretter hendelsene:
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
}Ikke-blokkerende polling
Bruk watcher.poll() for ikke-blokkerende kontroller, eller poll(timeout, unit) for venting med tidsavbrudd:
// 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-hendelse
Hvis hendelser hoper seg opp raskere enn applikasjonen behandler dem, signaliserer en OVERFLOW-hendelse at enkelte hendelser har gått tapt. Håndter dette på en kontrollert måte:
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
}Fullstendig fungerende eksempel
En komplett filovervåker som kjører i en bakgrunnstråd:
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();
}
}
}
}Overvåking av flere kataloger
Registrer flere kataloger med samme WatchService. Bruk den returnerte WatchKey-en for å identifisere hvilken katalog hendelsen kom fra:
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);Finne fullstendig filbane
Hendelsens context() returnerer bare filnavnet, ikke hele filbanen. Finn banen ved å løse den mot katalogen som overvåkes:
WatchEvent<Path> pathEvent = (WatchEvent<Path>) event;
Path filename = pathEvent.context();
Path fullPath = watchedDir.resolve(filename);
System.out.println("Full path: " + fullPath);Rekursiv katalogovervåking
WatchService overvåker bare den registrerte katalogen, ikke underkatalogene. For rekursiv overvåking kan De gå gjennom treet og registrere hver underkatalog:
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); }
});
}Frigjøring av ressurser
Lukk alltid WatchService når De er ferdig, slik at operativsystemressursene frigjøres:
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 automaticallyPraktisk bruksområde: hot reload av konfigurasjon
Bruk WatchService til å laste inn konfigurasjonen på nytt når filen endres:
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
}Begrensninger ved WatchService
Viktige begrensninger:
- Overvåker bare kataloger, ikke enkeltfiler
- Er ikke rekursiv som standard — registrer hver underkatalog manuelt
- På macOS: bruker polling internt (mindre responsivt enn Linux inotify)
- Kan gå glipp av raske endringsserier (OVERFLOW)
- WatchKey blir ugyldig hvis katalogen som overvåkes, slettes
Kort kontrollspørsmål
Etter at De har behandlet hendelser fra en WatchKey, hva må De kalle før WatchService kan levere flere hendelser for denne nøkkelen?
Oppsummering: WatchService
Viktig å huske:
- Registrer kataloger med hendelsene ENTRY_CREATE/MODIFY/DELETE
- take() blokkerer; poll() er ikke-blokkerende; poll(timeout, unit) brukes til venting med tidsavbrudd
- Kall alltid key.reset() etter at hendelsene er behandlet
- context() returnerer bare filnavnet — løs det mot katalogen som overvåkes for å finne hele filbanen
- Lukk WatchService med try-with-resources
- Rekursiv overvåking krever at hver underkatalog registreres
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «WatchService: overvåke filendringer» gratis?
Ja – hele teksten i «WatchService: overvåke filendringer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «WatchService: overvåke filendringer»?
Registrer en WatchService for å oppdage hendelser for filoppretting, endring og sletting i sanntid. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «WatchService: overvåke filendringer»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Path: representere filplasseringer
- Files-verktøyet: lese, skrive, kopiere og flytte
- Gå gjennom katalogtrær med Files.walk
- WatchService: overvåke filendringer