1. Обзор
Задолго до того, как API-интерфейс Java WatchService
был выпущен в Java 7, библиотека мониторинга ввода-вывода Apache Commons уже обращалась к тому же варианту использования для отслеживания местоположения или каталога файловой системы на предмет изменений.
В этой статье мы собираемся изучить различия между двумя API.
2. Зависимости Maven
Чтобы использовать Apache Commons IO, в pom
необходимо добавить следующую зависимость :
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
И, конечно же, служба часов является частью JDK, поэтому она не нуждается во внешних зависимостях.
3. Сравнение функций
3.1. Обработка, управляемая событиями
API WatchService
управляется событиями изменения файловой системы, инициируемыми операционной системой. Такой подход избавляет приложение от многократного опроса файловой системы на наличие изменений.
Библиотека Apache Commons IO Monitor, с другой стороны, опрашивает местоположение файловой системы с настраиваемым интервалом ожидания, вызывая метод listFiles () класса
File
. Этот подход тратит впустую циклы ЦП, особенно если не происходит никаких изменений.
3.2. Метод обратного вызова
WatchService
API не предоставляет методы обратного вызова. Вместо этого он предоставляет два типа методов опроса, чтобы проверить, доступны ли для обработки новые события изменений:
- Методы блокировки, такие как
poll()
(с параметром тайм-аута) иtake()
- Неблокирующий метод, такой как
poll()
(без параметра тайм-аута)
При использовании методов блокировки поток приложения начинает обработку только тогда, когда становятся доступными новые события изменения. Следовательно, ему не нужно продолжать опрос для новых событий.
Подробности и использование этих методов можно найти в нашей статье здесь .
Напротив, библиотека ввода-вывода Apache Commons предоставляет методы обратного вызова в интерфейсе FileAlterationListener
, которые вызываются при обнаружении изменения в местоположении или каталоге файловой системы.
FileAlterationObserver observer = new FileAlterationObserver("pathToDir");
FileAlterationMonitor monitor = new FileAlterationMonitor(POLL_INTERVAL);
FileAlterationListener listener = new FileAlterationListenerAdaptor() {
@Override
public void onFileCreate(File file) {
// code for processing creation event
}
@Override
public void onFileDelete(File file) {
// code for processing deletion event
}
@Override
public void onFileChange(File file) {
// code for processing change event
}
};
observer.addListener(listener);
monitor.addObserver(observer);
monitor.start();
3.3. Переполнение события
API WatchService
управляется событиями операционной системы. Следовательно, существует вероятность того, что буфер операционной системы, в котором хранятся события, переполнится, если приложение не сможет обработать события достаточно быстро. В этом сценарии запускается событие StandardWatchEventKinds.OVERFLOW , указывающее, что некоторые события потеряны или отброшены до того, как приложение сможет их прочитать.
Для этого требуется правильная обработка события ПЕРЕПОЛНЕНИЕ
в приложении, чтобы гарантировать, что приложение может обрабатывать любые внезапные события изменения, которые могут вызвать событие ПЕРЕПОЛНЕНИЯ
.
Библиотека Commons IO, с другой стороны, не основана на событиях операционной системы, и, следовательно, не возникает вопроса о переполнении.
В каждом опросе наблюдатель получает список файлов в каталоге и сравнивает его со списком, полученным в ходе предыдущего опроса.
- Если в последнем опросе найдено новое имя файла, на прослушивателе вызывается
onFileCreate() .
- Если имя файла, найденное в предыдущем опросе, отсутствует в списке файлов, полученном в результате последнего опроса, на прослушивателе вызывается
onFileDelete() .
- Если совпадение найдено, файл проверяется на наличие любых изменений атрибутов, таких как дата последнего изменения, длина и т. д. Если обнаружено изменение, в прослушивателе вызывается
onFileChange() .
4. Вывод
В этой статье нам удалось выделить ключевые различия двух API.
И, как всегда, полный исходный код примеров, использованных в этой статье, доступен в нашем проекте на GitHub .