Почему FindFirstFile / FindNextFile иногда видят файл в сетевой папке, а CopyFile — нет?

У меня есть функция, которая должна создавать резервную копию исходной папки путем копирования всех файлов из исходного в целевую папку. Функция использует цикл while, управляемый FindFirstFile / FindNextFileзатем вызывает CopyFile для каждого файла, найденного Find... функция.

Теперь, когда исходная папка является сетевым путем SMB (независимо от того, использую ли я подключенный диск или путь UNC), иногда случается, что FindNextFile «видит» файл, но CopyFile отказывается копировать файл. Код ошибки 2, т.е. ERROR_FILE_NOT_FOUND,

Мне было трудно в это поверить, поэтому я добавил вызов _access к функции резервного копирования, которая проверяет существование файла непосредственно перед CopyFile называется. Результат такой же как и для CopyFileт.е. _access сообщает, что файл не существует (код возврата -1 и errno 2, т.е. ENOENT).

Итак, мой главный вопрос: как это возможно, что FindFirstFile / FindNextFile «видит» файлы в сетевой папке, которые ни CopyFile ни _access можно увидеть?

Дополнительная информация / диагностика:

  • Проблемный файл — это файл, который создается непосредственно перед запуском функции резервного копирования. В частности, это работает следующим образом: процесс, который выполняется на клиентском компьютере, имеет сетевое подключение к процессу, который выполняется на сервере. Клиентский процесс сообщает серверному процессу создать файл. Предполагается, что это работает синхронно: только после того, как процесс сервера подтвердит, что он создал файл, клиентский процесс продолжит выполнять резервное копирование.
  • Я добавил механизм повтора в функцию резервного копирования. С этим, CopyFile а также_access внезапно начните видеть рассматриваемый файл примерно через 4 секунды повторной попытки. Это указывает мне на то, что действительно существует какая-то сетевая задержка. Похоже, что FindFirstFile / FindNextFile получить доступ к сетевому пути иначе, чем CopyFile / _access,

К сожалению, мои исследования на этот счет не дали никакой полезной информации, поэтому я могу только строить догадки. Если FindFirstFile / FindNextFile / CopyFile действительно, не очень хорошо работают вместе, знаете ли вы другой набор функций API поиска / копирования, которые работают более надежно?

4

Решение

Вероятно, это связано с тем, что SMB 2.0 в Windows поддерживает кэш, который обновляется только каждые 10 секунд.

Увидеть этот блог статья для получения дополнительной информации и программных решений.

Говорится:

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

Для разрешения / обхода в связанной статье упоминается:

Как мне управлять временем жизни локального кэша?

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

Под

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ LanmanWorkstation \ Параметры:

FileInfoCacheLifetime

FileNotFoundCacheLifetime

DirectoryCacheLifetime

Все они имеют тип REG_DWORD в секундах.

Программный обходной путь?

Зарегистрируйтесь для получения уведомлений об изменениях каталогов или файлов с помощью Win32 API.

Используйте API функции FindFirstChangeNotification (Windows) для регистрации
изменения.

7

Другие решения


По вопросам рекламы [email protected]