Without further ado, just look at the code:
FileAction.java
package com.tools.filewatch; /** * File change behavior enumeration * */ public enum FileAction { DELETE("ENTRY_DELETE"), CREATE("ENTRY_CREATE"), MODIFY("ENTRY_MODIFY"); private String value; FileAction(String value) { this.value = value; } public String getValue() { return value; } }
FileActionCallback.java
package com.tools.filewatch; import java.io.File; /** * Callback method for file operation * */ public abstract class FileActionCallback { public void delete(File file) { }; public void modify(File file) { }; public void create(File file) { }; }
WatchDir.java
package com.tools.filewatch; import java.io.File; import java.io.IOException; import java.nio.file.*; import java.nio.file.WatchEvent.Kind; import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; /** * Folder monitoring * */ public class WatchDir { private final WatchService watcher; private final Map<WatchKey, Path> keys; private final boolean subDir; /** * Construction method * * @param file file directory, cannot be a file * @param subDir * @throws Exception */ public WatchDir(File file, boolean subDir, FileActionCallback callback) throws Exception { if (!file.isDirectory()) throw new Exception(file.getAbsolutePath() + "is not a directory!"); this.watcher = FileSystems.getDefault().newWatchService(); this.keys = new HashMap<WatchKey, Path>(); this.subDir = subDir; Path dir = Paths.get(file.getAbsolutePath()); if (subDir) { registerAll(dir); } else { register(dir); } processEvents(callback); } @SuppressWarnings("unchecked") static <T> WatchEvent<T> cast(WatchEvent<?> event) { return (WatchEvent<T>) event; } /** * Observe the specified directory * * @param dir * @throws IOException */ private void register(Path dir) throws IOException { WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY); keys.put(key, dir); } /** * Watch the specified directory and include subdirectories * * @param start * @throws IOException */ private void registerAll(final Path start) throws IOException { Files.walkFileTree(start, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { register(dir); return FileVisitResult.CONTINUE; } }); } /** * Callback function for file changes * * @param callback */ @SuppressWarnings("rawtypes") void processEvents(FileActionCallback callback) { for (; ; ) { WatchKey key; try { key = watcher.take(); } catch (InterruptedException x) { return; } Path dir = keys.get(key); if (dir == null) { System.err.println("Operation not recognized"); continue; } for (WatchEvent<?> event : key.pollEvents()) { Kind kind = event.kind(); // Events may be lost or abandoned if (kind == StandardWatchEventKinds.OVERFLOW) { continue; } // Changes in directories may be files or directories WatchEvent<Path> ev = cast(event); Path name = ev.context(); Path child = dir.resolve(name); File file = child.toFile(); if (kind.name().equals(FileAction.DELETE.getValue())) { callback.delete(file); } else if (kind.name().equals(FileAction.CREATE.getValue())) { callback.create(file); } else if (kind.name().equals(FileAction.MODIFY.getValue())) { callback.modify(file); } else { continue; } // if directory is created, and watching recursively, then // register it and its sub-directories if (subDir && (kind == StandardWatchEventKinds.ENTRY_CREATE)) { try { if (Files.isDirectory(child, NOFOLLOW_LINKS)) { registerAll(child); } } catch (IOException x) { // ignore to keep sample readbale } } } boolean valid = key.reset(); if (!valid) { // remove inaccessible directories // Because the directory may be removed, it will be inaccessible keys.remove(key); // If the directory to be monitored does not exist, interrupt execution if (keys.isEmpty()) { break; } } } } }
Filewatch.java
package com.tools.filewatch; import java.io.File; public class Test { public static void main(String[] args) throws Exception { final File file = new File("C:\\test"); new Thread() { @Override public void run() { try { new WatchDir(file, true, new FileActionCallback() { @Override public void create(File file) { // TODO something... System.out.println("File created\t" + file.getAbsolutePath()); } @Override public void delete(File file) { // TODO something... System.out.println("File deleted\t" + file.getAbsolutePath()); } @Override public void modify(File file) { // TODO something... System.out.println("The file has been modified\t" + file.getAbsolutePath()); } }); } catch (Exception e) { e.printStackTrace (); } } }.start(); System.out.println("Monitoring folder:" + file.getAbsolutePath() + "changes"); } }