, , , , , , ,

I was looking a way to get notified me whenever there was a change in my particular file system.  For example, if a file modified/deleted in a directory or added a new file to the directory, I need to perform certain task like processing the file for data extraction.

Prior to Java 7, few options I have are,

– For Unix, add an cron job entry to poll the program in particular time interval

– Apply thread mechanism in my program to keep alive it and iterate in particular intervals etc…

How it would be if I have an option to get notified me whenever there is an event happens to my file/directory?. Java 7 brings this feature through WatcherService.

Here we see how to implement it.

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();

Java 7 introduced a new class java.nio.file.Path to locate a file in a file system.

Path dir = Paths.get(“c:\\data\\fileDir”);

C:\data\fileDir is the directory where I have my files. It will take either string or URI as a argument.

Next, 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:

  •                 ENTRY_CREATE – A directory entry is created.
  •                 ENTRY_DELETE – A directory entry is deleted.
  •                 ENTRY_MODIFY – A directory entry is modified.
  •                 OVERFLOW – Indicates that events might have been lost or discarded. You do not have to register for the OVERFLOW event to receive it.

Below code shows how to register path instance for all the above three event types.

Path dir = Paths.get(“c:\\data\\fileDir);

try {
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE,ENTRY_MODIFY);
} catch (IOException x) {

Below are the order of processing the events.

1. Get the watch key. There are three methods to get it.
i. poll
ii. poll(long, TimeUnit)
iii. take

2. Process the pending events for the key.

3. Retrieve the type of event by using the method “kind()”.

4. Retrieve the file name associated with the event. The file name is stored as the context of the event, so the context() method is used to retrieve it.

5. After the events for the key have been processed, you have to put the key back into a ready state by invoking reset method. If you fail to invoke reset() method this key will not receive any further events.

A watch key has a state. At any given time, its state might be one of the following:

Ready –                 indicates that the key is ready to accept events. When first created, a key is in the ready state.

Signaled –            indicates that one or more events are queued. Once the key has been signaled, it is no longer in the ready state until the reset method is invoked.

Invalid –                indicates that the key is no longer active. This state happens when one of the following events occurs:

–              The process explicitly cancels the key by using the cancel method.

–              The directory becomes inaccessible.

–              The watch service is closed.

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.

click here for sample program to see how it works.

Prerequisites: you should have java 7 installed in your system

Input: You have to supply one or two arguments. The arguments are either, your file system alone or file system with -r option (for recursive).

Below are the examples for how to run the program
i) java FileNotifier c:\data\fileDir —> Will notifies only for that particular directory
ii) java FileNotifier -r c:\data\fileDir –> Will notify changes in all the sub-directories as well (recursive)

Once you run it, the context will be active as long as you terminate it. Whenever you do modifications like changing a content of file resides in c:\data\fileDir directory, the event will be captured and printed in the console.