Java 7: NIO WatchService
In my previous post I have written many of the Java 7 features for developing Java Telnet Server.
Here I want to go deep into one such feature WatchService.
The WatchService is a very interesting feature of the new java.nio.file package in Java 7.
One of the more interesting is the WatchService, adding the capability to watch a directory for changes.
Watching Directory:
We have to create a File Path for the specific directory we want to watch.
Path:
Path faxFolder = Paths.get("C:\\foo");
The Path interface implements the register method that takes a WatchService object and varargs of type WatchEvent.Kind as arguments. There are 4 events to watch for:
WatchService watchService = FileSystems.getDefault().newWatchService();
faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, In my previous post I have written many of the Java 7 features for developing Java Telnet Server.
Here I want to go deep into one such feature WatchService.
The WatchService is a very interesting feature of the new java.nio.file package in Java 7.
One of the more interesting is the WatchService, adding the capability to watch a directory for changes.
The WatchService maps directly to the native file event notification mechanism, if available. If a native event notification mechanism is not available, then the default implementation will use polling. As a result, the responsiveness, ordering of events and details available are implementation specific.
Source Code:
Watching Directory:
We have to create a File Path for the specific directory we want to watch.
Path:
Path faxFolder = Paths.get("C:\\foo");
The Path interface implements the register method that takes a WatchService object and varargs of type WatchEvent.Kind as arguments. There are 4 events to watch for:
ENTRY_CREATE
ENTRY_DELETE
ENTRY_MODIFY
OVERFLOW
While the first 3 types are easy to understand, OVERFLOW indicates that events may been lost or discarded. A WatchService is created by calling FileSystem.newWatchService().
Watching a directory is accomplished by registering a Path object with the WatchService:
WatchService watchService = FileSystems.getDefault().newWatchService();
StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey watchKey = watchService.take();
As you can see above code register method returns a watchKey. The WatchKey is a token that represents the registration of the Path with the WatchService.
The WatchKey
As a result of the registration process, the WatchKey is in a ‘ready’ state and is considered valid. A WatchKey remains valid until one of the following occurs:
- WatchKey.cancel() is called.
- The directory being watched is no longer available.
- The WatchService object is closed.
When a change is detected, the WatchKey state is set to ‘signaled’ and it is placed in a queue for processing. Getting WatchKeys off the queue involves calling WatchService.poll() or
WatchService.take().
Here is a basic example:
WatchKey watchKey = watchService.poll(60,TimeUnit.SECONDS);//this will retrieve all the events for this watch key
List<WatchEvent.Kind<?>> events = watchKey.pollEvents();
boolean value = watchKey.reset()
The "reset" method sets the WatchKey state back to 'ready'(meaning listen for events) and returns a boolean indicating if the WatchKey is still valid. If there are any pending events, then the WatchKey will be re-queued, otherwise it will remain in the ready state until new events are detected.
How to process events
Now that we have detected an event, how do we determine:
- On which directory did the event happen? (assuming more than one directory registered)
- What was the actual event? (assuming listening for more than one event)
- What was the target of the event, i.e what Path object was created,deleted or updated?
Path watchedPath = (Path) watchKey.watchable();
for (WatchEvent<?> event : watchKey.pollEvents()) {
//returns the event type
StandardWatchEventKinds eventKind = event.kind();
//returns the context of the event
Path target = (Path)event.context();
}
There are two things that about the WatchService.
The WatchService does not pick up events for sub-directories of a watched directory.
We still need to poll the WatchService for events, rather than receive asynchronous notification.
Here is the sample output:
No comments:
Post a Comment