Кажется мне тем Файлом. Существует (), намного медленнее, когда файл не существует, или у пользователя нет доступа чем тогда, когда файл действительно существует.
действительно ли это верно?
Это не имеет смысла мне.
Обычно, когда вы ищете что-то в кучу вещей, вы не можете быть уверены в их отсутствии, если не обыскали все возможные места это могло быть. При поиске чего-либо (в большинстве видов коллекций) худший случай - когда элемент не существует в коллекции.
Я не тестировал конкретно File.Exists
, но очень сомневаюсь, что в этих случаях есть действительно заметная разница, если вы не делаете это тысячи раз. Как вы пришли к такому выводу?
File.Exists
is trapping exceptions. The overhead of raising and capturing an exception may contribute to poor performance.
File.Exists
works like this:
To check to see if the file exists, it tries to open the file... if an exception is thrown the file doesn't exist.
That process is slower than opening a file and no exception is thrown (which is when the file exists).
Я выполнил следующий тест, и, по крайней мере, на моем ПК время примерно такое же:
static void TestExists()
{
Stopwatch sw = Stopwatch.StartNew();
for ( int i = 0; i < 1000; i++ )
{
if ( !File.Exists( @"c:\tmp\tmp" + i.ToString() + ".tmp" ) )
Console.WriteLine( "File does not exist" );
}
Console.WriteLine( "Total for exists: " + sw.Elapsed );
sw = Stopwatch.StartNew();
for ( int i = 0; i < 1000; i++ )
{
if ( File.Exists( @"c:\tmp\tmp_" + i.ToString() + ".tmp" ) )
Console.WriteLine( "File exists" );
}
Console.WriteLine( "Total for not exists: " + sw.Elapsed );
}
Результаты были примерно такими же: (каждый запуск немного отличается, но примерно одинаков):
Total for exists: 00:00:00.0717181
Total for not exists: 00:00:00.0824266
Но по сети (от LAN до сервера на расстоянии одного прыжка), я обнаружил, что тест был немного медленнее, когда файлы действительно существовали. Я понюхал его, и в каждом направлении был только один пакет SMB.
Total for exists: 00:00:02.4028708
Total for not exists: 00:00:00.6910531
File.Exists
также создает экземпляр разрешения CLR перед проверкой существования файла для файла. Альтернативой (хотя я не пробовал для повышения производительности) является PathFileExists , если вы выполняете много проверок:
[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
private extern static bool PathFileExists(StringBuilder path);
void Exists()
{
// A StringBuilder is required for interops calls that use strings
StringBuilder builder = new StringBuilder();
builder.Append(@"C:\test.txt");
bool exists = PathFileExists(builder);
}
Файл и все его методы обычно работают с окнами файловые ручки.
Если вы выполняете много проверок, вам следует использовать:
FileInfo fiInfo = new FileInfo(@"c:\donotexists");
if (fiInfo.Exists)
return true;
Вместо того, чтобы работать внутренне с дескрипторами файлов, он смотрит на атрибуты файлов и работает намного быстрее. Кроме того, он не проверяет исключения, что является большим замедлением в .NET