Почему FileSystemWatcher создает несколько событий изменения, когда я копирую файл в каталог - PullRequest
4 голосов
/ 05 октября 2008

Я написал небольшое тестовое приложение, использующее .Net FileSystemWatcher, чтобы следить за каталогом. Когда я копирую файл большого размера (несколько Мб) в этот каталог, я получаю перечисленные ниже события (см. Скриншот - и игнорирую событие Delete для начала).

альтернативный текст http://robinwilson.homelinux.com/FSW.png

Я получаю созданное событие (как и ожидалось), но затем два измененных события (с интервалом примерно 0,7 секунды). Почему это? Это может вызвать серьезные проблемы в приложении, которое я планирую разработать - так как я попытался бы что-то сделать с файлом дважды (предположительно, один раз, прежде чем он закончил записываться!) Могу ли я что-нибудь сделать, чтобы это не произошло? Из того, что я прочитал в StackOverflow и в других местах, вы должны просто получить одно измененное событие, как только файл был изменен и затем закрыт. Почему я получаю два?

Ответы [ 2 ]

11 голосов
/ 05 октября 2008

В соответствии с документацией (см. Первый пункт в разделе События и размеры буфера ):

Обычные операции файловой системы могут вызывать более одного события. Например, при перемещении файла из одного каталога в другой могут возникать несколько событий OnChanged и некоторые события OnCreated и OnDeleted. Перемещение файла - это сложная операция, состоящая из нескольких простых операций, поэтому возникает несколько событий. Аналогично, некоторые приложения (например, антивирусное программное обеспечение) могут вызывать дополнительные события файловой системы, которые обнаруживаются FileSystemWatcher.

2 голосов
/ 05 октября 2008

Обычно копирующая программа делает это блоками, а не целым файлом сразу. Я не думаю, что вы можете сделать что-нибудь, чтобы избежать этого, вам придется принять свои алгоритмы, чтобы справиться с этим.

Вы можете попытаться открыть файл с исключительными правами на чтение, которые должны быть предоставлены вашей программе, только когда другая программа закончила копирование и закрыла файл. В противном случае вы получите IOException и можете дождаться следующего изменения. Но это не значит, что вы не должны иметь дело с событиями с множественными изменениями. Открытие текстового файла в блокноте и его временное сохранение приведет к возникновению событий изменения, но файл не будет заблокирован все время.

Другим подходом будет сбор затронутых файлов в течение определенного периода времени, а когда FileSystemWatcher прекращает генерировать события, обрабатывает все файлы одновременно.

...