Java NIO WatchService

#java #xml #nio #watchservice

#java #xml #nio #watchservice

Вопрос:

У меня есть Java project, в котором нам нужно продолжать прослушивать некоторый путь, чтобы определить, есть ли какой-либо новый XML-файл, и если true, нам нужно обработать его с помощью нескольких других правил.

WatchService отлично справляется с обнаружением, есть ли у меня новый файл для обработки, но я не смог управлять им, чтобы я мог прочитать файл, я просто возвращаю мне имя файла из события.

Есть ли какой-либо способ сделать это с помощью WatchService? Если нет, то к какому еще предложению обратиться?

Спасибо.

Комментарии:

1. Если у вас есть имя файла, разве вы не можете просто открыть файл?

2. Если под «просто именем файла» вы подразумеваете результат WatchEvent#context() , тогда просто сопоставьте его с каталогом, чтобы получить полный путь.

Ответ №1:

Конечно, вы можете легко к этому:

  1. Создайте службу просмотра:

      WatchService watchService = null;
    
     try {
         watchService = FileSystems.getDefault().newWatchService();
         Path path = get(pathToSee);
         path.register(watchService, new WatchEvent.Kind[]{ENTRY_MODIFY, ENTRY_CREATE}, SensitivityWatchEventModifier.HIGH);
         watchEvent(watchService, path);
         log.info("Watch Service has ben created!");
     } catch (IOException e) {
         log.error("Exception has ben throw when the service have tried to createWatchService()", e);
     }
      

Примечание: Если вам нужно добавить большое количество файлов, вы можете поместить:

 SensitivityWatchEventModifier.HIGH
  

Для повышения чувствительности.

  1. Следите, есть ли изменения в вашем каталоге:

      WatchKey key;
     while (true) {
         try {
             if ((key = watchService.take()) == null) break;
    
             for (WatchEvent<?> event : key.pollEvents()) {
                 log.info("Event kind:"   event.kind()
                           ". File affected: "   event.context()   ".");
    
                 String fileName = event.context().toString();
                 File directory = path.toFile();
                 yourService.readContent(directory, fileName);
             }
             key.reset();
         } catch (InterruptedException | IOException e) {
             log.error("InterruptedException when try watchEvent()"   e);
         }
     }
      
  2. И, наконец, вы можете делать с этой информацией все, что хотите:

      try (BufferedReader br = new BufferedReader(new FileReader(directory   "/"   fileName))) {
         String strLine;
         while ((strLine = br.readLine()) != null) {
                 }
             }
         }
     }
      

Советы:

  1. Для этого вы можете создать отдельный поток или использовать Spring @Async для создания отдельного потока для обработки этой информации и повышения параллелизма в вашем приложении.

  2. Вы также можете использовать Apache Commons you для этого!

например:

 public void getAll() throws Exception {
    FileAlterationObserver observer = new FileAlterationObserver(pathToSee);
    observer.addListener(new FileAlterationListenerAdaptor() {

        @SneakyThrows
        @Override
        public void onFileCreate(File file) {
            
            
        }

        @Override
        public void onFileDelete(File file) {
            
        }
    });
}