#java #xml #nio #watchservice
#java #xml #nio #watchservice
Вопрос:
У меня есть Java project, в котором нам нужно продолжать прослушивать некоторый путь, чтобы определить, есть ли какой-либо новый XML-файл, и если true, нам нужно обработать его с помощью нескольких других правил.
WatchService отлично справляется с обнаружением, есть ли у меня новый файл для обработки, но я не смог управлять им, чтобы я мог прочитать файл, я просто возвращаю мне имя файла из события.
Есть ли какой-либо способ сделать это с помощью WatchService? Если нет, то к какому еще предложению обратиться?
Спасибо.
Комментарии:
1. Если у вас есть имя файла, разве вы не можете просто открыть файл?
2. Если под «просто именем файла» вы подразумеваете результат
WatchEvent#context()
, тогда просто сопоставьте его с каталогом, чтобы получить полный путь.
Ответ №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
Для повышения чувствительности.
-
Следите, есть ли изменения в вашем каталоге:
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); } }
-
И, наконец, вы можете делать с этой информацией все, что хотите:
try (BufferedReader br = new BufferedReader(new FileReader(directory "/" fileName))) { String strLine; while ((strLine = br.readLine()) != null) { } } } }
Советы:
-
Для этого вы можете создать отдельный поток или использовать Spring @Async для создания отдельного потока для обработки этой информации и повышения параллелизма в вашем приложении.
-
Вы также можете использовать 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) {
}
});
}