当文件不存在时,为什么File.Exists()会慢得多?

时间:2010-02-08 22:36:33

标签: c# .net file

对我来说,当文件不存在或者用户没有访问权限时文件存在时File.Exists()要慢得多。

这是真的吗?

这对我没有意义。

5 个答案:

答案 0 :(得分:42)

File.Exists正在捕获异常。提升和捕获异常的开销可能导致性能不佳。

File.Exists的工作原理如下:

要检查文件是否存在,它会尝试打开文件...如果抛出异常,则文件不存在。

该过程比打开文件慢,并且不会抛出任何异常(即文件存在时)。

答案 1 :(得分:32)

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);
}

答案 2 :(得分:10)

通常当你搜索一堆东西时,你不能确定它们是否存在,除非你已经搜索了所有可能的地方。当搜索某些东西(在大多数类型的集合中)时,最糟糕的情况是该集合中不存在该项目。

我没有特别对File.Exists进行基准测试,但我非常怀疑在这些情况下存在明显的差异,除非你做了数千次。你是如何得出这个结论的?

答案 3 :(得分:3)

我进行了以下测试,至少在我的电脑上,时间大致相同:

  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

但是在网络上(在局域网上到服务器一跳之后),我发现当文件确实存在时,测试速度会慢一些。我闻了闻,每个方向只有一个SMB数据包。

Total for exists: 00:00:02.4028708
Total for not exists: 00:00:00.6910531

答案 4 :(得分:-4)

文件及其所有方法通常适用于Windows文件句柄。

如果你做了很多检查,你应该使用:

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

它不是在内部使用文件句柄,而是查看文件属性并且速度要快得多。此外,它不会检查异常,这在.NET中是一个很大的减速