Проверка существования файла после переименования папки возвращает неверное значение на общем ресурсе UNC - PullRequest
8 голосов
/ 08 марта 2012

В Windows 7 (или на сервере) у нас есть папка на общем ресурсе UNC (UNC для нескольких компьютеров, , а не localhost). Мы переименовываем эту папку, а затем проверяем наличие файла в новой папке. Несмотря на то, что он существует, File.Exists требуется почти 5 секунд, чтобы вернуть ему значение true.

Полное воспроизведение можно найти на https://github.com/davidebbo/NpmFolderRenameIssue. Вот основной код:

// This file doesn't exist yet
// Note that the presence of this existence check is what triggers the bug below!!
Console.WriteLine("Exists (should be false): " + File.Exists("test/test2/myfile"));

// Create a directory, with a file in it
Directory.CreateDirectory("test/subdir/test");
File.WriteAllText("test/subdir/test/myfile", "Hello");

// Rename the directory
Directory.Move("test/subdir/test", "test/test2");

var start = DateTime.UtcNow;

// List the files at the new location. Here, our file shows up fine
foreach (var path in Directory.GetFiles("test/test2"))
{
    Console.WriteLine(path);
}

for (; ; )
{
    // Now do a simple existence test. It should also be true, but when
    // running on a (cross machine) UNC share, it takes almost 5 seconds to become true!
    if (File.Exists("test/test2/myfile")) break;

    Console.WriteLine("After {0} milliseconds, test/test2/myfile doesn't show as existing",
        (DateTime.UtcNow - start).TotalMilliseconds);
    Thread.Sleep(100);
}

Console.WriteLine("After {0} milliseconds, test/test2/myfile correctly shows as existing!",
    (DateTime.UtcNow - start).TotalMilliseconds);

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

Вопросы : чем это объясняется? Какой лучший способ избежать этого?

ПРИМЕЧАНИЕ : эта проблема изначально возникла при использовании npm (Node Package Manager) в Windows. Код, который я имею здесь, является портом репродукции C #. См. https://github.com/isaacs/npm/issues/2230 для оригинальной проблемы Node / npm. Цель состоит в том, чтобы найти способ решить эту проблему.

Ответы [ 3 ]

10 голосов
/ 08 марта 2012

David, Перенаправитель реализует отрицательный кэш "File Not Found", который не позволяет клиенту затопить сервер запросами на файл not found.Время кеширования по умолчанию составляет 5 секунд, но вы можете изменить значение реестра FileNotFoundCacheLifetime, чтобы управлять кешем или отключить его, установив для этого значения значение 0.

Подробности: http://technet.microsoft.com/en-us/library/ff686200(v=WS.10).aspx

1 голос
/ 14 января 2015

Как только я узнал о кеше «File Not Found», я смог обойти эту проблему, используя объект FileInfo, который реализует метод Refresh().Ваш код может сделать это вместо этого:

FileInfo testFile = new FileInfo("test/test2/myfile");
Console.WriteLine("Exists (should be false): " + testFile .Exists);
Directory.Move("test/subdir/test", "test/test2");
testFile.Refresh();

// the FileInfo object should now be refreshed, and a second call to Exists will return a valid value
if (testFile.Exists)
{
    ...
}
1 голос
/ 08 марта 2012

В сетевом коде есть несколько уровней кэширования. Это может замедлить время появления файла.

Решением будет не использование общих файловых ресурсов, а создание простой клиент-серверной архитектуры, где сервер возвращает существование файла из локальной файловой системы. Это действительно должно ускорить время обнаружения предметов.

Я полагаю, что если вы попытаетесь открыть файл, даже если File.Exists скажет, что он еще не существует, его следует открыть правильно, чтобы вы могли использовать информацию о существовании сервера. Если это не сработает, вы можете просто добавить опцию загрузки в архитектуру сервер / клиент.

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