Search code examples
javawatchservice

Get location of file created using WatchService


I am using WatchService to watch a folder and its subfolders for new files created. However when a file is created the WatchService gives the name of the file that is created, not its location. Is there a way to get the absolute/relative path of the file that was created.

A crude way to solve this issue is to search for the filename in all the subfolders and find the one with the latest create date. Is there a better way to do this?


Solution

  • If you register a WatchService on dir directory, when to get full path is simple:

    // If the filename is "test" and the directory is "foo",
    // the resolved name is "test/foo".
    Path path = dir.resolve(filename);
    

    It works, because WatchService monitors only one directory. If you want to monitor subfolders, you have to register new WatchServices.

    Answer to your unformatted comment (This would solve your problem)

    public static void registerRecursive(Path root,WatchService watchService) throws IOException { 
       WatchServiceWrapper wsWrapper = new WatchServiceWrapper();
    
       // register all subfolders 
       Files.walkFileTree(root, new SimpleFileVisitor<Path>() { 
          public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
             wsWrapper.register(watchService, dir);
             return FileVisitResult.CONTINUE; 
          } 
       });  
    
       wsWrapper.processEvents();
    }
    
    public class WatchServiceWrapper {
       private final Map<WatchKey,Path> keys;
    
       public WatchServiceWrapper () {
          keys = new HashMap<>();
       }
    
       public void register(WatchService watcher, Path dir) throws IOException {
          WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
          keys.put(key, dir);
       }
    
       public void processEvents() {
          for (;;) {
            // wait for key to be signalled
            WatchKey key;
            try {
                key = watcher.take();
            } catch (InterruptedException x) {
                return;
            }
    
            Path dir = keys.get(key);
            if (dir == null) {
                System.err.println("WatchKey not recognized!!");
                continue;
            }
    
            //get fileName from WatchEvent ev (code emitted)
            Path fileName = ev.context();
    
            Path fullFilePath = dir.resolve(fileName);
    
            //do some other stuff
          }
       }
    }