Каков наилучший способ проверить наличие файлов в общей сетевой папке в Windows Vista? - PullRequest
3 голосов
/ 13 февраля 2009

Мой вопрос - небольшая вариация вопроса Как лучше всего проверить, существует ли файл в Windows? , с некоторыми конкретными оговорками. В частности, данные расположены на подключенном диске, и используется протокол SMB 2.0. (По определению, для этого требуется, чтобы диск был сопоставлен с компьютером с Vista на компьютере с Vista или Server 2008.)

Проблема с ответами, опубликованными в ответ на вышеуказанный вопрос, заключается в том, что SMB 2.0 кэширует набор метаданных, включая имена файлов в заданном каталоге. В результате, если вы проверяете наличие файла, который был просто создан, то функции _access, access, GetFileAttributes и CreateFile (и, возможно, другие) будут использовать кэшированную информацию для ответа на вопрос " этот файл существует? " Если файл был совсем недавно создан другим пользователем, кеш указывает, что файл отсутствует, несмотря на тот факт, что он действительно существует. Я настроил тестовые среды для проверки этого, и я могу подтвердить, что no SMB2-трафик генерируется клиентом в течение нескольких секунд [предположительно, кэш-память истекает каждые 5 секунд или около того].

Кто-нибудь еще видел это? (Если да, нашли ли вы обходной путь, отличный от добавления задержки / повтора?) Кто-нибудь знает какой-либо API, аналогичный приведенному выше, который может проверять существование файла без использования кэша SMB? Или, что еще лучше, кто-нибудь знает о Windows API, который просто выдает кэшированные метаданные SMB?

Ответы [ 3 ]

1 голос
/ 03 ноября 2009

Хотя это и не является программным решением, я нашел эффективный обходной путь (с помощью поддержки Microsoft). Я хотел бы опубликовать обходной путь здесь на случай, если кто-то еще разочарован этим так же, как и я. Поскольку это поведение является «функцией» SMB2, Microsoft предоставила следующие записи реестра для переопределения срока действия кэша метаданных по умолчанию:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\FileInfoCacheLifetime 
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\FileNotFoundCacheLifetime 
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\DirectoryCacheLifetime

Каждое из этих значений - это DWORD, которые можно установить в соответствии с вашими потребностями. (Установка их в 0 на SMB2-клиенте была эффективной при решении моей проблемы.)

0 голосов
/ 24 мая 2009

Позвоните open(path, O_CREAT | O_EXCL, mode) и проверьте результат. Это приводит к ошибке, если файл уже существует. Конечно, это запишет в кэш SMB и даст правильные результаты, иначе это будет очень ненадежно. Таким образом, если вызов выполнен успешно, файл file не существует, но существует сейчас, поэтому вам может потребоваться удалить его (зависит от логики приложения). Если вызов не удался, файл уже существовал.

0 голосов
/ 03 марта 2009

Просто откройте его.

...