How to track the folder for changes in java?

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) { // Do stuff } } 

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.

+7
source share
2 answers

Why don't you store the metadata file in each folder ( recursively ), in this metadata file you can store the file list and modified date and size for each file. Your stream should compare this metadata file in each folder with current files present in it. This way you can detect any changes in this folder.

Remember that you must do this recursively for each subfolder inside this. And the metadata file should be updated with every scan. Hope this helps.

+1
source

in my case this code was successful:

 try { Path rootFolder = Paths.get(ctxProperties.getProperty("rootFolder")); WatchService watcher = rootFolder.getFileSystem().newWatchService(); rootFolder.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); while (true) { WatchKey watchKey = watcher.take(); if (watchKey != null) { for (WatchEvent event : watchKey.pollEvents()) { if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) { String fileName = rootFolder.toString() + "/" + event.context().toString(); String messageStr = convertFileToString(fileName); if (messageStr != null) { try { sendMessage(jmsPublisher, messageStr, getJmsProperties()); moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("successFolder"), ".ok"); LOGGER.info("JMS message successfully sent"); sleep(Long.parseLong(ctxProperties.getProperty("sleepBetweenMsgMse"))); } catch (Exception e) { moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok"); } } else { LOGGER.error("ERROR: error parsing file content to string with file: " + fileName); moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok"); } } } boolean valid = watchKey.reset(); if (!valid) { LOGGER.error("ERROR: the watcher is no longer valid, the directory is inaccessible"); break; } } else { LOGGER.error("ERROR: the watcher is null or not watchable"); break; } } } catch (InterruptedException interruptedException) { LOGGER.error("InterruptedException: thread got interrupted",interruptedException); } catch (Exception exception) { LOGGER.error("Exception: " + exception.getMessage(), exception); } 
0
source

All Articles