2015-01-28 2 views
4

При работе с WatchService я обнаружил, что если я удалю файл в просматриваемом каталоге, он запускает ENTRY_MODIFY, за которым следует событие ENTRY_DELETE.WatchService (Windows 7): при удалении файла он запускает как события ENTRY_MODIFY, так и ENTRY_DELETE?

Я понимаю, что технически файл может быть изменен перед удалением, но действительно ли ожидаемое поведение, при котором удаление файла вызывает ENTRY_MODIFY (которого, по-видимому, никто не заботится)?

Чтобы справиться с этим, я должен был добавить условие, чтобы проверить перед обжигом проходя по событию ENTRY_MODIFY:

  if (eventKind == ENTRY_CREATE) { 
       listener.fileCreated(file); 
      } else if (eventKind == ENTRY_MODIFY) { 
       if (Files.exists(fullPath, LinkOption.NOFOLLOW_LINKS)) { 
        listener.fileChanged(file); 
       } 
      } else if (eventKind == ENTRY_DELETE) { 
       listener.fileDeleted(file); 
      } 

Это есть лучший способ справиться с этой проблемой (функция)?

+1

Я считаю, что это ожидается, и единственная строка кода, которую вы используете для обработки этого поведения, кажется простым решением для меня. – colti

+0

@colti: У меня еще не было возможности протестировать Linux. Есть ли разница в поведении между Windows и Linux здесь? –

+1

Возможно, но я не знаю точно. Реализация Linux использует inotify, если вы хотите прочитать об этом: http://man7.org/linux/man-pages/man7/inotify.7.html – colti

ответ

1

Я могу только подтвердить эту проблему. Из комментариев и из моих собственных наблюдений событие ENTRY_MODIFY запускается непосредственно перед удалением файла, и вам приходится иметь дело с ним.

Предположим, у нас есть две нити. Один делает Files.delete(), другой просматривает каталог и пытается прочитать измененные файлы. Любое из следующих может произойти:

  1. Files.delete() только удается изменить и удалить файл, перед тем как событие подхватывается наблюдающей нитью. Затем работает техника проверки существования файла после ENTRY_MODIFY.
  2. Files.delete() вызов может завершиться неудачно (возврат false), так как файл уже открыт наблюдающей нитью.

Единственное разрешение, кажется, чтобы игнорировать все IOExceptions в наблюдающей нити и повторите Files.delete() вызовов несколько раз.

Я только пытался удалить файлы из одной JVM с помощью Files.delete(). Я не пытался удалить из другого процесса в системе. Проблема воспроизводится на Windows 7 ~ 10 с помощью NTFS, возможно, не на других ОС.

Я призываю других отредактировать этот ответ и добавить свои наблюдения.