Мониторинг файлов вместе с Java NIO

Мониторинг файлов вместе с Java NIO

Java NIO или Java New I/O это крайне полезный пакет, позволяющий использовать асинхронный ввод/вывод. Сегодня с помощью java.nio.file , следуя паттерну Observer , мы реализуем свой класс для наблюдения за состоянием файлов в папке. Наш план:

  1. Первым делом создадим WatchService.
  2. Потом переменную Path , указывающую на папку, которую планируем мониторить.
  3. Далее бесконечный цикл наблюдения. Когда происходит интересующее нас событие, класс WathKey помещает его в очередь наблюдателя. После обработки события мы должны вернуть ключ в состояние готовности, вызвав метод reset() . Если метод вернёт false , то ключ больше не действителен, цикл можно завершить.

Данный код должен вывести в консоль следующее:

Watch Service API довольно низкоуровневая штука, мы реализуем на его основе свой более высокоуровневый API. Начнём с написания класса FileEvent . Так как это объект состояния события, его необходимо унаследовать от EventObject и передать в конструктор ссылку на файл, за котором будем наблюдать.

Теперь создаём интерфейс слушателя FileListener , наследуемый от java.util.EventListener . Этот интерфейс должны реализовать все слушатели, которые будут подписываться на события нашей папки.

Наконец, создаём класс, который будет хранить в себе список слушателей, подписанных на папку. Назовём его FileWatcher .

Хорошей идеей будет реализовать класс FileWatcher как Runnable , чтобы иметь возможность запускать наблюдение в виде демона, если указанная папка существует.

Так как в методе run() будут создаваться объекты WatchService , использующие внешние ресурсы (ссылки на файлы), все события будем хранить в статическом списке. Такая реализация позволит вызвать метод close() из любого потока, ждущего ключ. А также вызвать исключение ClosedWatchServiceException , чтобы отменить наблюдение без утечки памяти.

Когда происходит интересующее нас событие и путь корректен, мы уведомляем слушателей о событии. Если была создана новая директория, то для неё будет инициализирован новый экземпляр FileWatcher .

Полная реализация класса FileWatcher будет выглядеть так:

Последний штрих – создание класса FileAdapter , простейшей реализации интерфейса FileListener .

Чтобы убедиться в работоспособности написанного кода, можно использовать несложный класс FileWatcherTest .

Несмотря на кажущуюся простоту, наблюдатели – мощный инструмент автоматизации процессов. С помощью них, например, можно автоматически перезапускать скрипты на продакшене, если один из них был изменён. Уменьшение человеческого фактора – благо для программиста.

А используете ли вы наблюдателей в своей работе? Или, может быть, реактивное программирование?