Lets think of an use, a java program should monitor a folder and it should alert if a new file is created. We may have a FTP folder where in an external system will post a file and our program has to monitor that FTP folder and when a new file arrives we need to read it or email it.
So we have got the above real time scenarios and how do we solve it using Java? Java version 7 provided an update for IO package. NIO package was a significant update in this version. It has got a set of interfaces and classes to help this job done.
WatchService and Watchable provides the framework to watch registered object for changes using Java. Imagine we have a file editor and it has a file loaded. At the same time, we have opened that same file using another editor and edited it. Now the other editor will alert with a message saying “The file is edited, do you want to load the latest version?”
So to watch this file for changes we can use WatchService and Watchable. Like this we can watch any objects for changes. When we watch files and folder we need to obtain an interface to the underlying native file system. For that we can use the FileSystems class.
Following source code, provides implementation for watching a folder for a new file. We obtain the instance of WatchService using the FileSystems class. Then the path to be watched is registered with this instance of WatchService for the CREATE event. When a new file is created we get the event with the context. In this sample, we just get the file name and print it in the console. Here we can fork our business service, like send an email or read the file and store it in database.
package com.javapapers.java; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; public class MonitorDirectory { public static void main(String[] args) throws IOException, InterruptedException { Path faxFolder = Paths.get("./fax/"); WatchService watchService = FileSystems.getDefault().newWatchService(); faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); boolean valid = true; do { WatchKey watchKey = watchService.take(); for (WatchEvent> event : watchKey.pollEvents()) { WatchEvent.Kind kind = event.kind(); if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) { String fileName = event.context().toString(); System.out.println("File Created:" + fileName); } } valid = watchKey.reset(); } while (valid); } }
Create a new file in /ftp/ folder and you can see the output. “ftp” folder should be created in the project root.
Comments are closed for "Monitor a Folder using Java".
Joe,
Great explanation as always but I might have noticed a typo in the code. Shouldn’t the target be set to ./ftp/ and not ./fax/?
Either way thanks for the hard work you put into these. I learn a lot every time I read one.
Thanks,
George
Nice article as always Joe.
Nice article, Thanks joe.
Good one!
Nice article..thanks joe.. :)
interesting post.
Cool feature of Java 7 , but Joe just pick it for us. Thanks Joe , felling shame to request you for more article rather it is better to wait for new article , will experiment with this toady :)
one quick question.
How can we monitor a mysql table…i mean if someone updated or inserted a record into a table in mysql then there should be notification to client application who is using that database through jdbc.
Please help.
nice job..!!!!
thank you it was very helpful and easy to understand.
Nice article JOE. thank you very much :)
I have altered this program for all events delete, modified.
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class MonitorDirectory {
public static void main(String[] args) throws IOException,
InterruptedException {
Path faxFolder = Paths.get(“E:\\workspace”);
WatchService watchService = FileSystems.getDefault().newWatchService(); faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_DELETE,StandardWatchEventKinds.ENTRY_MODIFY);
boolean valid = true;
do {WatchKey watchKey = watchService.take();
for (WatchEvent event : watchKey.pollEvents()) { WatchEvent.Kind kind = event.kind(); if(StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) { String fileName = event.context().toString(); System.out.println(“File Created:” + fileName);
} if (StandardWatchEventKinds.ENTRY_DELETE.equals(event.kind())) {
String fileName = event.context().toString(); System.out.println(“File deleted:” + fileName); } if (StandardWatchEventKinds.ENTRY_MODIFY.equals(event.kind())) { String fileName = event.context().toString(); System.out.println(“File modified:” + fileName);
} }
valid = watchKey.reset();
} while (valid);
}
}
use a trigger
Really cool stuff
Thanks for updating :)
nice article joe….this concept is new for me..
Good article. Thanks Joe.
Yeah, It’s a new concept in 1.7..good to see this..nice explanation…keep it up..
nice article
How to do the same requirement without java 8 version
nice explanation as always, thanks a lot
i m getting error that updated code..pls help me
C:\Users\Satheesh>javac Monitordirjoe.java
Monitordirjoe.java:5: cannot find symbol
import java.nio.file.StandardWatchEventKinds;
^
symbol: class StandardWatchEventKinds
location: package java.nio.file
Monitordirjoe.java:14: cannot find symbol
faxFolder.register(watchService,StandardWatchEventKinds.ENTRY_CREATE);
^
symbol: variable StandardWatchEventKinds
location: class Monitordirjoe
Monitordirjoe.java:22: package StandardWatchEventKinds does not exist
if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind()))
^
3 errors
good
Good one thanks for telling me know hidden feature of the java, but I have one concern here since it is very tight while loop won’t allow the other thread to work efficiently.
Can’t we implement the concept of observer listener.. i.e when there is change in file then only it notify us
Using Timer Task and Collections
check your jdk path
simple…use thread…..
This is a nice article… But in case, if I am adding any files inside the files of ftp folder, for them it is not working… plz help me how to make it..
Thanks!
Thanks Joe..
The above code only monitors root directory.. If i need to monitor root and its corresponding sub directory what changes we need to do to the code.. Kindly help..
Joe using throws with main is not a good practice isn’t it?? can you tell me why you used throws with main, do you have any particular reason to do this?
thanks ..
please provide some tutorial for junit and hsqldb
Hi Joe
I want to know what is the exact difference between char and byte ?
plz explain me with out range and memory is there anything else ?
I am eagerly waiting for u r replay
I need same thing for java 6
Thank you very much, it has been quite helpfull for me.
Hi,
How do I monitor a folder on another Server?
My java class is running on a separate server and the Folder is on another server.
Path faxFolder = Paths.get(“ftpServer”);
How do I provide the secure channel here?
Appreciate your help on this?
can I monitor my complete drive using this?
somewhere i have read that this concept is using multithreading kind of & so not suggest for watch on drive.
Instead of printing out the event on the console i.e “File created…” If I make a call to JOptionPane.showMessagedDialog I realise that it does’t work, how can i handle this? Thanks
Its Very good article joe
Thanks, nice explanation
hi nice code. but can we capture the timestamp (i.e time for creating , modifying or deleting a file) of a file?
if so then can u please help me out for the same
i dont want to use quartz but need to monitor my folder for every 10mins?????????????
I tried your program, and tried to modify it to print the original path of the file name. but when i do this
if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
Path path = (Path)event.context();
File file = path.toFile();
System.out.println(“Created file name : ” + file.getAbsolutePath());
it prints only the virtual path where the current program is running. How to get the actual path printed?
Nice article!!!
Can this program be updated to monitor remote directories?
I have setup an FTP server on my mobile device and I want to listen to any file arrivals on one of my folders on my mobile.
So far I have managed to upload and download files to my remote folder using Apache commons net library but I am not able to use watch service to monitor the remote folder. It works perfect for local directory though.
Thanks