I have the following code to monitor 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) {
All this works fine as long as file modifications (in my case, most often added) are performed 1 on 1 with a slight delay in each addition. However, if I drag and drop or add multiple files at the same time. This code detects an event only for the first file, and not for the rest. I even added an exception time in nanoseconds, but that didn't help. I am wondering all this code is the right way to do this. Can anybody help me. thanks.
Hossein
source share