prasanth
prasanth

Reputation: 115

Watching a Directory and sub directory for create, modify and Changes in java

I have written some code for detecting changes in C:/java/newfolder it is working good.

This is the code:

import java.nio.file.*;
import java.util.List;

public class DirectoryWatchExample {
  public static void testForDirectoryChange(Path myDir) {
    try {
      WatchService watcher = myDir.getFileSystem().newWatchService();
      myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
          StandardWatchEventKinds.ENTRY_DELETE,
          StandardWatchEventKinds.ENTRY_MODIFY);

      WatchKey watckKey = watcher.take();

      List<WatchEvent<?>> events = watckKey.pollEvents();
      for (WatchEvent event : events) {
        if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
          System.out.println("Created: " + event.context().toString());
        }
        if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
          System.out.println("Delete: " + event.context().toString());
        }
        if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
          System.out.println("Modify: " + event.context().toString());
        }
      }

    } catch (Exception e) {
      System.out.println("Error: " + e.toString());
    }
  }

  public static void main(String[] args) {
    Path myDir = Paths.get("c:/java/newfolder/");
    // define a folder root
    testForDirectoryChange(myDir);
  }
}

now i'm watching only the directory itself. But i need to watch only all the sub directory.

for example: c:/java/newfolder/folder1, c:/java/newfolder/folder2, c:/java/newfolder/folder3......etc

I tried using this sub directory string in the example above:

c:/java/newfolder/*..

I need to watch the all sub directory. Can you give me a solution?

Upvotes: 6

Views: 8559

Answers (4)

Thomas Beauvais
Thomas Beauvais

Reputation: 1656

Here is what I came with..

    final WatchService watcher = FileSystems.getDefault().newWatchService();

    final SimpleFileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>(){
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
        {
            dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

            return FileVisitResult.CONTINUE;
        }
    };

    Files.walkFileTree(Paths.get("/directory/to/monitor"), fileVisitor);

Upvotes: 2

Tim Bender
Tim Bender

Reputation: 20442

What you want to do is register the WatchService recursively and continue to register it upon subsequent ENTRY_CREATE events. A complete example is provided by Oracle here: http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java

Normally I wouldn't place a post with a single link, however I doubt Oracle will be taking down a fairly basic tutorial and the answer is far too verbose. Just in case though, examples are easily found by searching for "java watchservice recursive".

Upvotes: 11

Nicolas Rinaudo
Nicolas Rinaudo

Reputation: 6178

I'm not familiar with the Path API, so take the following with a grain of salt.

You're registering one directory for monitoring, and will receive notifications whenever one of its direct descendants is modified / created / deleted.

The first thing you need to do is register all of its subdirectories for watching:

// Used to filter out non-directory files.
// This might need to filter '.' and '..' out, not sure whether they're returned.
public class DirectoryFilter implements FileFilter {
    public boolean accept(File file) {
        return file.isDirectory();
    }
}


// Add this at the end of your testForDirectoryChange method
for(File dir: myDir.toFile().listFiles(new DirectoryFilter())) {
    testForDirectoryChange(dir.toPath());
}

This will recursively explore your file structure and register every directory for watching. Note that if your directory tree is too deep, recursion might not be an acceptable solution and you might need to 'iterify' it.

The second thing you need to do is, whenever you receive a directory creation event, not forget to register the new directory for monitoring.

That's how I'd do it anyway, but not having a valid Java 1.7 installation at hand, I can't test it. Do let me know if it works!

Upvotes: 0

Luis Sep
Luis Sep

Reputation: 2412

So what you want is listing the files/subdirectories within a directory? You can use:

File dir = new File("c:/java/newfolder/");
File[] files = dir.listFiles();

listFiles() gives you the Files in a directory or null it it's not a directory.

Then you can do:

for (File file: files){
     if (file.listFiles != null){
          //It's a subdirectory
          File [] subdirFiles = file.listfiles;
     }
}

Upvotes: -1

Related Questions