I want to watch a directory for file changes. And I used WatchService in java.nio. I can successfully listen for file created event. But I can't listen for file modify event. I checked official java tutorial, but still struggling.
Here is the source code.
import static java.nio.file.LinkOption.NOFOLLOW_LINKS; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.OVERFLOW; import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import java.io.File; import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.WatchEvent; import java.nio.file.WatchEvent.Kind; import java.nio.file.WatchKey; import java.nio.file.WatchService; public class MainWatch { public static void watchDirectoryPath(Path path) { // Sanity check - Check if path is a folder try { Boolean isFolder = (Boolean) Files.getAttribute(path, "basic:isDirectory", NOFOLLOW_LINKS); if (!isFolder) { throw new IllegalArgumentException("Path: " + path + " is not a folder"); } } catch (IOException ioe) { // Folder does not exists ioe.printStackTrace(); } System.out.println("Watching path: " + path); // We obtain the file system of the Path FileSystem fs = path.getFileSystem(); // We create the new WatchService using the new try() block try (WatchService service = fs.newWatchService()) { // We register the path to the service // We watch for creation events path.register(service, ENTRY_CREATE); path.register(service, ENTRY_MODIFY); path.register(service, ENTRY_DELETE); // Start the infinite polling loop WatchKey key = null; while (true) { key = service.take(); // Dequeueing events Kind<?> kind = null; for (WatchEvent<?> watchEvent : key.pollEvents()) { // Get the type of the event kind = watchEvent.kind(); if (OVERFLOW == kind) { continue; // loop } else if (ENTRY_CREATE == kind) { // A new Path was created Path newPath = ((WatchEvent<Path>) watchEvent) .context(); // Output System.out.println("New path created: " + newPath); } else if (ENTRY_MODIFY == kind) { // modified Path newPath = ((WatchEvent<Path>) watchEvent) .context(); // Output System.out.println("New path modified: " + newPath); } } if (!key.reset()) { break; // loop } } } catch (IOException ioe) { ioe.printStackTrace(); } catch (InterruptedException ie) { ie.printStackTrace(); } } public static void main(String[] args) throws IOException, InterruptedException { // Folder we are going to watch // Path folder = // Paths.get(System.getProperty("C:\\Users\\Isuru\\Downloads")); File dir = new File("C:\\Users\\Isuru\\Downloads"); watchDirectoryPath(dir.toPath()); } }
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 method java. io. File. list() is used to obtain the list of the files and directories in the specified directory defined by its path name.
io. File. isDirectory() checks whether a file with the specified abstract path name is a directory or not. This method returns true if the file specified by the abstract path name is a directory and false otherwise.
Actually you have incorrectly subscribed to events. Only last listener has been registered with ENTRY_DELETE events type.
To register for all kind of events at once you should use:
path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
Warning! Shameless self promotion!
I have created a wrapper around Java 1.7's WatchService
that allows registering a directory and any number of glob patterns. This class will take care of the filtering and only emit events you are interested in.
DirectoryWatchService watchService = new SimpleDirectoryWatchService(); // May throw watchService.register( // May throw new DirectoryWatchService.OnFileChangeListener() { @Override public void onFileCreate(String filePath) { // File created } @Override public void onFileModify(String filePath) { // File modified } @Override public void onFileDelete(String filePath) { // File deleted } }, <directory>, // Directory to watch <file-glob-pattern-1>, // E.g. "*.log" <file-glob-pattern-2>, // E.g. "input-?.txt" ... // As many patterns as you like ); watchService.start();
Complete code is in this repo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With