Я разрабатываю фрагмент кода на C, который использует ReadDirectoryChangesW () для мониторинга изменений в каталоге в Windows. Я прочитал соответствующие записи MSDN для ReadDirectoryChangesW () и структуры FILE_NOTIFY_INFORMATION, а также несколько других частей документации. На данный момент мне удалось контролировать несколько каталогов без каких-либо явных проблем в самом мониторинге. Проблема состоит в том, что имена файлов, помещенные в структуру FILE_NOTIFY_INFORMATION этой функцией, не являются каноническими.
В соответствии с MSDN они могут быть в длинной или короткой форме. Я нашел несколько сообщений, которые предлагают кэширование как коротких, так и длинных путей для обработки этого случая. К сожалению, согласно моему собственному тестированию в системе Windows 7 этого недостаточно для устранения проблемы, потому что для каждого имени файла не существует только двух альтернатив. Проблема в том, что в имени пути КАЖДЫЙ КОМПОНЕНТ может быть в длинной или короткой форме. Следующие пути могут относиться к одному и тому же файлу:
C: \ PROGRA ~ 1 \ MyProg ~ 1 \ MYDATA ~ 1.TXT
C: \ PROGRA ~ 1 \ MyProg ~ 1 \ MyDataFile.txt
C: \ PROGRA ~ 1 \ MyProgram \ MYDATA ~ 1.TXT
C: \ PROGRA ~ 1 \ MyProgram \ MyDataFile.txt
c: \ Program Files \ MYPROG ~ 1 \ MYDATA ~ 1.TXT
...
и, насколько я могу судить по моему тестированию с использованием cmd.exe, все они вполне приемлемы. По сути, число допустимых имен путей для каждого файла растет экспоненциально с количеством компонентов в его имени пути.
К сожалению, ReadDirectoryChangesW (), похоже, заполняет свой выходной буфер именами файлов, предоставленными системному вызову, который вызывает каждую операцию. Например, если вы используете команды cmd.exe для создания, переименования, удаления файла e.t.c. В файлах FILE_NOTIFY_INFORMATION будет содержать имена файлов, указанные в командной строке.
Теперь в большинстве случаев я мог использовать GetLongPathName () и друзей, чтобы получить уникальный путь для моего использования. К сожалению, этого нельзя сделать при удалении файлов - к тому времени, как я получу уведомление, файл уже исчезнет, и функции Get * PathName () не будут работать.
В настоящий момент я думаю об использовании более обширного кэширования для определения того, какие альтернативные имена путей используются приложениями для каждого файла, что будет обрабатывать любой случай, кроме случая, когда кто-то решает удалить файл на ровном месте, невидимый смешанный путь. И я думаю о творческом извлечении данных из событий модификации родительского каталога и возвращаюсь к проверке действительного каталога для этого случая.
Есть предложения, как сделать это проще?
PS1: Хотя журналы изменений справились бы с этим эффективно (я надеюсь), я не верю, что смогу их использовать из-за их связи с NTFS и отсутствия прав администратора для моего приложения. Я бы предпочел не идти туда, если я не буду вынужден.
PS2: Пожалуйста, имейте в виду, что я пишу в основном для Unix, так что будьте осторожны ...