Friday, June 14, 2013

Monitor File System Directory using Java 7 Watch Service


A watch service that watches registered objects for changes and events. For example a file manager may use a watch service to monitor a directory for changes so that it can update its display of the list of files when files are created or deleted.

The WatchService API is fairly low level, allowing you to customize it. You can use it as is, or you can choose to create a high-level API on top of this mechanism so that it is suited to your particular needs.


The following java code will help you to create simple Directory watching service:
 
import static java.nio.file.StandardWatchEventKinds.*;

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;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class DirectoryWatcherService {
     
      public static void main(String[] args) {
           
            WatchService watchService = null;
            try {
                  //Create new WatchService object
                  watchService = FileSystems.getDefault().newWatchService();
                 
                  //create path object with the absolute path of the directory that you want to monitor 
                  Path path = Paths.get("D:\\test");
                 
                  //Register Path with all three events
                  WatchKey watchKey = path.register(watchService, ENTRY_CREATE, ENTRY_DELETE,ENTRY_MODIFY);
                 
                                   
                  while(true){
                        //if event not triggered within 100 seconds, poll() will return null
                        WatchKey queuedWatchKey = watchService.poll(5, TimeUnit.SECONDS);
                       
                        if(queuedWatchKey == null) throw new NullPointerException("Event not triggered.");
                       
                        //get all the pending events as list
                        List<WatchEvent<?>> events = queuedWatchKey.pollEvents();
                       
                        for(WatchEvent<?> event : events){
                              //context() used to retrieve file name stored as the context of the event
                              Path target = (Path) event.context();
                              System.out.println("Event: " + event.kind());
                              System.out.println("File name: "+target.getParent()+"\\"+target.getFileName());
                        }
                       
                        if(!watchKey.reset()){
                              // reset() used to put the key back to ready state.
                        }
                  }
           
            } catch (InterruptedException e) {
            } catch (IOException e) {
            } catch (NullPointerException e) {
                  System.out.println(e.getMessage());
            } finally {
                  try {
//Close watchService object
                        if(watchService != null)
                              watchService.close();
                  } catch (IOException e) {
                        System.out.println("Failed to close watchService.");
                  }
            }

      }

}


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.