Watching a Directory for Changes

The java.nio.file package provides a file change notification API, called the Watch Service API.

This API enables you to register a directory (or directories) with the watch service. When registering, you tell the service which types of events you are interested in:
1:File creation.
2:File deletion.
3:File Modification.

When the service detects an event of interest, it is forwarded to the registered process.

The registered process has a thread (or a pool of threads) dedicated to watching for any events it has registered for. When an event comes in, it is handled as needed.

Creating watcher service

The first step is to create a new WatchService by using the newWatchService method in the FileSystem class, as follows:

WatchService watcher = FileSystems.getDefault().newWatchService()

Registering for Events

We Can register one or more objects with the watch service.Any object that implements the Watchable interface can be registered.
The Path class implements the Watchable interface, so each directory to be monitored is registered as a Path object.

When registering an object with the watch service, you specify the types of events that you want to monitor. The supported StandardWatchEventKinds event types follow:

  1. ENTRY_CREATE – A directory entry is created.
  2. ENTRY_DELETE – A directory entry is deleted.
  3. ENTRY_MODIFY – A directory entry is modified.
Registering for Events
1
2
3
WatchService watcher = FileSystems.getDefault().newWatchService()
Path dir = Paths.get("C:\\data\\temp\\mydir\\");
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

Directory Watching Example

Putting all above together. We can now go ahead and look at a complete and practical example.

In below example we are going to watch directory for all the changes and will process the events.

Directory Watching Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;


public class DirectoryChangeListeners {

public static void main(String[] args) throws InterruptedException {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("C:\\data\\temp\\");
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
System.out.println("Watch Service registered for dir: " + dir.getFileName());
WatchKey key;
while ((key = watcher.take())!=null)
{
for (WatchEvent<?> event : key.pollEvents()) {

WatchEvent.Kind<?> kind = event.kind();

@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path fileName = ev.context();

if(kind==ENTRY_CREATE)
{
System.out.println("New File Added, file Name " + fileName);
}
if(kind==ENTRY_DELETE)
{
System.out.println("File Deleted " + fileName);
}

if (kind == ENTRY_MODIFY ) {
System.out.println("File Modified " + fileName);
}
}

boolean valid = key.reset();
if (!valid) {
break;
}
}

} catch (IOException ex) {
System.err.println(ex);
}
}
}

Key Points

Three methods are available for Retrieving events :
  1. poll – Returns a queued key, if available. Returns immediately with a null value, if unavailable.
  2. poll(long, TimeUnit) – Returns a queued key, if one is available. If a queued key is not immediately available, the program waits until the specified time. The TimeUnit argument determines whether the specified time is nanoseconds, milliseconds, or some other unit of time.
  3. take – Returns a queued key. If no queued key is available, this method waits.
Reset key

After the events for the key have been processed, you need to put the key back into a ready state by invoking reset. If this method returns false, the key is no longer valid and the loop can exit. This step is very important. If you fail to invoke reset, this key will not receive any further events.

When to Use and Not Use This API

The Watch Service API is designed for applications that need to be notified about file change events. It is well suited for any application, like an editor or IDE, that potentially has many open files and needs to ensure that the files are synchronized with the file system. It is also well suited for an application server that watches a directory, perhaps waiting for .jsp or .jar files to drop, in order to deploy them.

This API is not designed for indexing a hard drive. Most file system implementations have native support for file change notification. The Watch Service API takes advantage of this support where available. However, when a file system does not support this mechanism, the Watch Service will poll the file system, waiting for events.

Share Comments