Почему Файл. Существует () намного медленнее, когда файл не существует?

Кажется мне тем Файлом. Существует (), намного медленнее, когда файл не существует, или у пользователя нет доступа чем тогда, когда файл действительно существует.

действительно ли это верно?

Это не имеет смысла мне.

19
задан RLB 5 December 2017 в 13:54
поделиться

5 ответов

Обычно, когда вы ищете что-то в кучу вещей, вы не можете быть уверены в их отсутствии, если не обыскали все возможные места это могло быть. При поиске чего-либо (в большинстве видов коллекций) худший случай - когда элемент не существует в коллекции.

Я не тестировал конкретно File.Exists , но очень сомневаюсь, что в этих случаях есть действительно заметная разница, если вы не делаете это тысячи раз. Как вы пришли к такому выводу?

10
ответ дан 30 November 2019 в 01:53
поделиться

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).

42
ответ дан 30 November 2019 в 01:53
поделиться

Я выполнил следующий тест, и, по крайней мере, на моем ПК время примерно такое же:

  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
3
ответ дан 30 November 2019 в 01:53
поделиться

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);
}
32
ответ дан 30 November 2019 в 01:53
поделиться

Файл и все его методы обычно работают с окнами файловые ручки.

Если вы выполняете много проверок, вам следует использовать:

FileInfo fiInfo = new FileInfo(@"c:\donotexists");
if (fiInfo.Exists)
    return true;

Вместо того, чтобы работать внутренне с дескрипторами файлов, он смотрит на атрибуты файлов и работает намного быстрее. Кроме того, он не проверяет исключения, что является большим замедлением в .NET

-4
ответ дан 30 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: