#java #watchservice
#java #watchservice
Вопрос:
Я просто следовал этому руководству, чтобы использовать WatchService
API. Я понятия не имею, почему использовать WatchEvent<?>
вместо WatchEvent<Path>
, если я использую последний, нет необходимости приводить, или есть какие-либо другие ситуации, которые WatchService
можно использовать для мониторинга событий, отличных от пути?
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) {
return (WatchEvent<T>)event;
}
void processEvents() {
for (; ; ) {
...
//why doesn't the poolEvents() return WatchEvent<Path>
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
...
//here he use a static method cast() to SuppressWarnings the unchecked warning
WatchEvent<Path> ev = cast(event);
}
}
}
Ответ №1:
Javadoc WatchService говорит:
Файловые системы могут сообщать о событиях быстрее, чем они могут быть получены или обработаны, и реализация может налагать неопределенное ограничение на количество событий, которые она может накапливать. Если реализация сознательно отбрасывает события, то она организует метод pollEvents ключа для возврата элемента с типом события ПЕРЕПОЛНЕНИЯ. Это событие может использоваться потребителем в качестве триггера для повторного изучения состояния объекта.
Стандартный набор watcheventkinds.ПЕРЕПОЛНЕНИЕ имеет тип WatchEvent.Kind<Object>
, и я считаю, что именно поэтому pollEvents должен возвращать список WatchEvent<?>
, а не WatchEvent<Path>
. Javadoc для ПЕРЕПОЛНЕНИЯ также упоминает:
Контекст для этого события зависит от реализации и может быть нулевым
именно поэтому тип события переполнения должен быть WatchEvent<Object>
.
Обратите внимание, что в руководстве, на которое вы ссылались, предлагается следующее:
Извлеките тип события с помощью метода kind . Независимо от того, для каких событий зарегистрирован ключ, можно получить событие ПЕРЕПОЛНЕНИЯ. Вы можете выбрать обработку переполнения или игнорировать его, но вы должны проверить его.
Поэтому вам следует добавить в свой код следующее (если вы еще этого не сделали):
if (kind == OVERFLOW) {
continue;
}