Java 7 have brought in Watcher Service API in its NIO (Non-blocking IO) package which allows us to monitor a particular folder for any changes like addition, modification, deletion of files. This very useful when you want to trigger some file processing action or alike on any file change event. Thus we do not need to use any thrid party API any more and is fairly simple to work with.
So let's dive in...
First create an object of WatchService
Create WatchQueueReader object, and create a thread with it.
You can actually this way make your application monitor different directories for file changes, and run the operation is separate threads.
Register this WatchService for a given directory like the following:
Note: If you want to monitor only creation, or modify then register only with those Watch event kinds.
The Watch Service API does not allow registering an individual file. We’ll get a java.nio.file.NotDirectoryException if trying to do so.
Next, write an infinite loop to repeatedly poll the events fired by the watcher and process the events accordingly.
It’s very important that the key must be reset after the events have been processed. If not, the key won’t receive further events.
Often, you might have a need to pick-up all files in the monitored folder which might have accumulated while your application was not running. Since, WatchService only picks up the events, so we can simulate the event just by modifying the LastModified with the same value as it is now. This would ideally trigger the MODIFY event, without actually making any change to the metadata value.
So let's dive in...
First create an object of WatchService
WatchService watchFolder = pathToFolder.getFileSystem().newWatchService();
Create WatchQueueReader object, and create a thread with it.
You can actually this way make your application monitor different directories for file changes, and run the operation is separate threads.
WatchQueueReader watchQueueReader = new WatchQueueReader(watchFolder);
Thread th1 = new Thread(watchQueueReader, "FILE_INPUT_DIRECTORY");
th1.start();
Register this WatchService for a given directory like the following:
Path pathToFolder = Paths.get("c:/some_file_path_to_monitor");
pathToFolder.register(watchFolder, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
Note: If you want to monitor only creation, or modify then register only with those Watch event kinds.
The Watch Service API does not allow registering an individual file. We’ll get a java.nio.file.NotDirectoryException if trying to do so.
WatchKey key = watchService.take();
Thread t = Thread.currentThread();
Next, write an infinite loop to repeatedly poll the events fired by the watcher and process the events accordingly.
while (key != null && !mStop) {
for (WatchEvent event : key.pollEvents()) {
if (t.getName().equals("FILE_INPUT_DIRECTORY")) {
// Process the file
log.info("FILE_INPUT_DIRECTORY: " + event.context());
/**
* do something here with the file
* event.context() will give the file name
* event.kind() will tell what kind of event occurred
*/
}
key.reset();
key = watchService.take();
}
}
It’s very important that the key must be reset after the events have been processed. If not, the key won’t receive further events.
Often, you might have a need to pick-up all files in the monitored folder which might have accumulated while your application was not running. Since, WatchService only picks up the events, so we can simulate the event just by modifying the LastModified with the same value as it is now. This would ideally trigger the MODIFY event, without actually making any change to the metadata value.
private static void triggerWatchService(File dir) throws IOException {
File[] dirContent = dir.listFiles();
for (File f : dirContent) {
if (!f.isDirectory()) {
log.debug("Processing existing file: " + f.getName());
f.setLastModified(f.lastModified());
}
}
}
0 comments:
Post a Comment