I have the below code for monitoring a folder for any changes in java:
public class FolderWatcher
{
// public List<Event> events = new ArrayList<Event>();
public static Event call() throws IOException, InterruptedException
{
LOG.info("Watching folder");
Path _directotyToWatch = Paths.get("data/input-files"); // this will be put in the configuration file
WatchService watcherSvc = FileSystems.getDefault().newWatchService();
WatchKey watchKey = _directotyToWatch.register(watcherSvc, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
watchKey = watcherSvc.take();
for (WatchEvent<?> event : watchKey.pollEvents())
{
WatchEvent<Path> watchEvent = castEvent(event);
LOG.info(event.kind().name().toString() + " " + _directotyToWatch.resolve(watchEvent.context()));
String eventName = event.kind().name();
String fileName = _directotyToWatch.resolve(watchEvent.context()).toString();
watchKey.reset();
return new Event(eventName, fileName);
}
return null;
}
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> castEvent(WatchEvent<?> event)
{
return (WatchEvent<T>) event;
}
}
and:
public abstract class AbstractWatcher
{
abstract void eventDetected(Event event);
private final ScheduledExecutorService threadpool;
public AbstractWatcher(ScheduledExecutorService threadpool)
{
this.threadpool = threadpool;
}
public AbstractWatcher()
{
threadpool = Executors.newSingleThreadScheduledExecutor();
}
public void handle()
{
final FolderWatcherHandler handler = new FolderWatcherHandler();
final Runnable r = new Runnable()
{
@Override
public void run()
{
try
{
Event event = FolderWatcher.call();
if (event != null)
{
handler.eventDetected(event);
}
}
catch (IOException e)
{
LOG.error("failed to watch the update", e);
}
catch (InterruptedException e)
{
LOG.info("thread interrupted", e);
Thread.currentThread().interrupt();
return;
}
}
};
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
threadpool.shutdown();
}
});
threadpool.scheduleWithFixedDelay(r, 0, 1, TimeUnit.NANOSECONDS);
}
}
and:
public class FolderWatcherHandler extends AbstractWatcher
{
@Override
public void eventDetected(Event event)
{
// Do stuff
}
}
This whole thing works perfect as long as modifications of files(in my case mostly adding) is done 1 by 1 with a small delay within each addition. However, if I drag and drop, or add several files at the same time. This code only detects the event for the first file and not the rest. I even put the excecution time in Nanoseconds but it didn't help. I am wondering of this whole code is a currect way of doing this. Can someone help me. thanks.
Why don't you store a metadata
file in each folder (recursively
), in that metadata
file you can store file list
and modified date
and size
of each file. Your thread should compare this metadata
file in each folder with the current files
present in the same.
That is how you can detect any change within that folder.
Remember you should do it recursively for each subfolder
within that. And the metadata
file should be updated with each scan.
Hope this helps..
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