← Back to Advanced Java Course | Chapter 13: Java NIO | Lesson 4 of 5

Java WatchService

WatchService lets a program monitor a directory for file system changes like creation, deletion, or modification, instead of repeatedly polling the directory manually.

What is WatchService?

WatchService, part of NIO.2, lets a program monitor a directory for file system changes like creation, deletion, or modification, instead of repeatedly polling the directory's contents manually.

Example: What is WatchService?

java
import java.nio.file.*;
public class Main {
	public static void main(String[] args) throws Exception {
		WatchService watcher = FileSystems.getDefault().newWatchService(); // no manual polling needed
		System.out.println("WatchService created");
		watcher.close();
	}
}

Registering a Directory

A directory is monitored by calling register on its Path, passing the WatchService and the specific kinds of events to watch for, such as ENTRY_CREATE, ENTRY_DELETE, or ENTRY_MODIFY.

Example: Registering a Directory

java
// Import java.nio.file.* so it can be used by its short name
import java.nio.file.*;
// Import java.nio.file.StandardWatchEventKinds.* so it can be used by its short name
import static java.nio.file.StandardWatchEventKinds.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws Exception {
		Path dir = Files.createTempDirectory("watch-demo");
		WatchService watcher = FileSystems.getDefault().newWatchService();
		dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
		// Print a line to the console
		System.out.println("Registered " + dir);
		watcher.close();
	}
}

Watching for File Creation

Calling take() on a WatchService blocks until a registered event actually occurs, and the returned WatchKey's pollEvents method then returns every matching event that has happened since it was last checked.

Example: Watching for File Creation

java
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Path dir = Files.createTempDirectory("watch-demo");
		WatchService watcher = FileSystems.getDefault().newWatchService();
		dir.register(watcher, ENTRY_CREATE);
		Files.createFile(dir.resolve("new.txt"));
		WatchKey key = watcher.take(); // blocks until the event occurs
		for (WatchEvent<?> event : key.pollEvents()) {
			System.out.println(event.kind() + " " + event.context());
		}
		watcher.close();
	}
}

Watching for Modification and Deletion

ENTRY_MODIFY reports when an existing file's content changes and ENTRY_DELETE reports when a file is removed, letting a program react differently depending on exactly which kind of file system change occurred.

Example: Watching for Modification and Deletion

java
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Path dir = Files.createTempDirectory("watch-demo");
		Path file = Files.createFile(dir.resolve("data.txt"));
		WatchService watcher = FileSystems.getDefault().newWatchService();
		dir.register(watcher, ENTRY_MODIFY, ENTRY_DELETE);
		Files.writeString(file, "changed"); // triggers ENTRY_MODIFY
		WatchKey key = watcher.take();
		for (WatchEvent<?> event : key.pollEvents()) {
			System.out.println(event.kind());
		}
		watcher.close();
	}
}

Processing Watch Events in a Loop

A typical WatchService usage is an infinite loop that calls take() to wait for events, processes each one, and then calls reset() on the key so it can continue reporting future events on that same directory.

Example: Processing Watch Events in a Loop

java
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Path dir = Files.createTempDirectory("watch-demo");
		WatchService watcher = FileSystems.getDefault().newWatchService();
		dir.register(watcher, ENTRY_CREATE);
		Files.createFile(dir.resolve("a.txt"));
		WatchKey key = watcher.take();
		for (WatchEvent<?> event : key.pollEvents()) {
			System.out.println("Event: " + event.kind());
		}
		key.reset(); // continues reporting future events
		watcher.close();
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Not calling key.reset() after processing events, so the key stops delivering later events.
  2. Using the event's context path directly, when it is only the file name relative to the watched folder; resolve it against the directory.
  3. Expecting one event per save, when editors often cause several ENTRY_MODIFY events for one file.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.