FileSystemWatcher не сообщает об изменениях в заблокированном файле

Я наблюдаю за папкой, используя FileSystemWatcher, например:

watcher = new FileSystemWatcher(folder);
watcher.NotifyFilter = NotifyFilters.Size;
watcher.Changed += changedCallback;

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

Тем не менее, получается, что если я создаю файл в этой папке, и я устанавливаю его режим общего доступа в FileShare.Read, а затем я пишу в него, я не получу никаких уведомлений, пока файл не будет закрыто. Другой обходной путь - открыть файл (например, в блокноте), что, по-видимому, приводит к обновлению его состояния, и затем мое приложение для мониторинга получает уведомление. Еще один обходной путь - это обновление, которое я могу сделать в проводнике Windows, что снова приводит к обновлению состояния файла.

Интересно, если я смотрю на проводник Windows во время внесения изменений, я замечаю, что:

  1. Если файл доступен для чтения и записи, его размер будет сразу же обновлен в проводнике Windows, как только я его сохраню.
  2. Если Файл доступен только для чтения, его размер НЕ будет обновляться немедленно в Windows Explorer, если я не обновлю окно вручную.

Похоже, что мое приложение для мониторинга использует то же поведение, что и Windows Explorer. Я думал о запуске потока, который будет просто сканировать файлы в папке, но мне интересно, есть ли что-нибудь более элегантное в этом случае.

Кстати, я использую Win7, и я не уверен что эта проблема возникает и в других версиях Windows.

Спасибо!

РЕДАКТИРОВАТЬ : Использование ReadDirectoryChanges в C ++ дало мне точно такие же результаты. Реализация темы, о которой я говорил ранее, также не помогла. Мне интересно, что на самом деле делает F5 в Windows Explorer, потому что это приводит к тому, что об изменении сообщается.

13
задан tanascius 9 April 2013 в 13:18
поделиться

3 ответа

Решение проблемы не в том, чтобы открывать файлы, а в том, чтобы ЧИТАТЬ из них. Достаточно прочитать даже один байт, и механизм кеша Windows запишет содержимое файла на диск, что позволит вам их прочитать.

В итоге я реализовал поток, который просматривал все файлы, открывал их и считывал из них байт. Это вызвало их изменение и инициировало событие в объекте FileSystemWatcher.

Причина, по которой Windows Explorer F5 также работает, заключается в том, что Windows фактически считывает содержимое файла, чтобы отобразить расширенное содержимое (например, эскизы). Как только файл читается, кеш сначала записывает на диск, вызывая событие в FSW.

10
ответ дан 1 December 2019 в 22:37
поделиться

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

Решение (если возможно) - вызвать Flush для файла, который вы пишете. Если вы отслеживаете изменения, внесенные другими приложениями, все, конечно, может усложниться.

2
ответ дан 1 December 2019 в 22:37
поделиться

Да, Explorer использует тот же API, что и FileSystemWatcher. Как вы узнали, есть только один, ReadDirectoryChangesW().

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

Подробности в этой теме (остерегайтесь очень медленного сервера). Сегодня это все еще не удается со всеми примененными обновлениями Win7.

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

4
ответ дан 1 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: