Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Java WatchService – filesystem monitoring

Java WatchService – filesystem monitoring

Since Java 7 there are many great APIs for working with files. In this tutorial we present WatchService that can be used to easily monitor filesystem directories for changes!

To use WatchService correctly one has to do the following things:

  1. Create a WatchService using FileSystem API.
  2. Register Watchable in the WatchService for selected event types.
    Path is Watchable, so can be registered.
  3. Wait for watch event(s).
    Each Watchable is identified by WatchKey, from which events can be taken.
  4. Process events.
    Note that we have to check the kind of event, because it may happen that too much has happened :-) and there was an overflow in events queue, which means that we need to re-check the resource. Also event.context() is the modified resource.
  5. Reset key state to Ready
    If you don’t – you won’t receive further events!

Implementing such functionality, before advent of Java 7 must have been a real pain! Now it is so simple.

The code:

In this example we’re monitoring modifications in /var/log directory:


import java.nio.file.*;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;

public class WatchServiceExample {

    public static void main(String[] args) throws IOException {
        Path logs = Paths.get("/var/log");
        WatchServiceExample example = new WatchServiceExample();

    private final WatchService watcher;

    public WatchServiceExample() throws IOException {
        watcher = FileSystems.getDefault().newWatchService();

    private void monitor(Path dir) throws IOException {
        // See StandardWatchEventKinds for more event types.
        dir.register(watcher, ENTRY_MODIFY);

        System.out.println("Starting monitoring of: " + dir);

        boolean monitor = true;
        while (monitor) {
            WatchKey key = waitForChange();

            if (key == null) {

            for (WatchEvent<?> event : key.pollEvents()) {
                if (event.kind() == OVERFLOW) {
                    System.err.println("Overflow event: rechecking.");

                // Modified path is relative to parent:
                Path modifiedPath = (Path) event.context();
                System.out.printf("%s modified %d times.%n",
                        modifiedPath, event.count());

                // Reset to receive further events:
                // False means that the key became invalid.
                monitor = key.reset();

        System.err.printf("The key for %s is no longer valid!%n", dir);


    private WatchKey waitForChange() {
        try {
            return watcher.take();
        } catch (InterruptedException e) {
            System.err.println("Error while waiting for key: "
                    + e.getMessage());
        return null;

Note that WatchService has three methods for getting watchables:

  1. poll()
    Immediately get and remove the first watchable or return null.
  2. poll(long timeout, TimeUnit unit)
    Like poll(), but wait for specified time if there are no changes.
  3. take()
    Get and remove the first watchable (wait forever if there are no changes).

Remember that key reset is very important, because without it the key won’t receive further notifications!

Sample results produced by the above program:

Starting monitoring of: /var/log
auth.log modified 1 times.
syslog modified 1 times.
auth.log modified 1 times.
auth.log modified 1 times.
auth.log modified 1 times.
auth.log modified 1 times.

You can do here any kind of processing – loading the files in GUI, sending emails, showing alerts to a user, reloading configurations, loading new classes, or whatever you can imagine! :-)

Share with the World!