【问题标题】:Is File.Exists an expensive operation?File.Exists 是一项昂贵的操作吗?
【发布时间】:2010-12-15 00:30:10
【问题描述】:

回复:http://msdn.microsoft.com/en-us/library/system.io.file.exists.aspx

有谁知道这是否是一个特别缓慢或锁定的操作,可能会影响大型环境中的服务器性能?

【问题讨论】:

  • 还要注意 File.Exists() 几乎不需要被调用。它通常用于验证未来的 IO 操作,但它不能真正做到这一点,因为文件的存在可能会在调用 Exists 和执行 IO 操作之间发生变化。通常最好只尝试正在验证的操作,看看它是否有效。显然,这方面的反例有很多,您的应用可能属于其中之一。
  • 另一个使用 IO.File.Exists 的例子是在显示之前查看图像是否存在,如果不存在则显示替代方案。
  • 如果您在一个目录中有很多文件或目录,我发现它很昂贵。例如,在单个目录中有大约 10,000 个文件/目录后,使用File.Exists 处理该目录中的文件/目录会非常缓慢。比目录为空时慢 10 - 100 倍。随着更多文件/目录的添加,它会呈指数级恶化。所以要注意这一点。

标签: .net file io exists


【解决方案1】:

我认为不是(文件操作在大多数操作系统上都经过大量优化和缓存),并且大多数其他操作更可能是这里的罪魁祸首(套接字、数据库访问、一般处理等)。但是,像往常一样,最好的方法是实际分析您的应用程序并查看它是否是热点。

【讨论】:

    【解决方案2】:

    File.Exisits 使用 kernel32.dll FindFirstFile 打开该文件的处理程序。如果结果句柄无效,则返回 false。如果有效,它将用 LastAccessTime、CreationTime、文件大小等所有内容填充数据结构。然后返回真。没有任何阻碍。

    【讨论】:

      【解决方案3】:

      最好在您的环境中运行一些测试。我有一个应用程序可以每秒执行 10,000+ 次,而不会影响我的系统。我认为这相当快。

      【讨论】:

        【解决方案4】:

        锁号慢,取决于您将其与什么进行比较。就 I/O 而言,它相当便宜,但与其他操作相比,I/O 总体上通常很慢。所以,如果你必须使用它,它不会伤害太深。但是,我尽量不要调用它超过真正必要的次数! :-)

        【讨论】:

          【解决方案5】:

          在计算中,实际上没有“昂贵的操作”这样的东西,除非你考虑到它与什么相关的昂贵。

          例如,在现实世界中,2.000.000 美元购买一个物品会很贵吗?如果是巴哈马的价格呢?那会贵吗?一盒牛奶怎么样?贵吗?

          您需要考虑的是,就您打算执行的整体操作而言,File.Exists 是否成本高昂,以及您是否真的有任何替代方案。

          如果没有其他选择,贵不贵有关系吗?

          例如,如果您执行 1 次检查文件是否存在,然后如果存在,则将其加载并花一个小时处理它,那么我认为它不会被认为是昂贵的。

          但是,如果你在一个循环中调用它 10 次,以确定一个文件是否存在,然后如果存在,只需增加一个数字,那么它可能是你在那里执行的最昂贵的单个操作。

          您可以确定的唯一方法是实际测量该方法调用所花费的时间,与您在同一操作中的其他时间相比。

          【讨论】:

            【解决方案6】:

            在 2016 年,它似乎不是很贵,File.ExistsPathFileExists (Why is File.Exists() much slower when the file does not exist?) 之间似乎也没有真正的区别。我可以衡量的唯一区别是检查不存在的文件比检查现有文件更快:

            (在 SSD 上测试)

            [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private extern static bool PathFileExists(StringBuilder path);
            
            void Main()
            {
                var sw = Stopwatch.StartNew();
                for (int i = 0; i < 10000; i++)
                {
                    File.Exists(@"c:\Home\Temp\test_.log");
                }
                sw.Stop();
                sw.Dump("File.Exists = false");
            
                sw = Stopwatch.StartNew();
                for (int i = 0; i < 10000; i++)
                {
                    File.Exists(@"c:\Home\Temp\test.log");
                }
                sw.Stop();
                sw.Dump("File.Exists = true");
            
                var sb = new StringBuilder(@"c:\Home\Temp\test_.log");
                sw = Stopwatch.StartNew();
                for (int i = 0; i < 10000; i++)
                {
                    PathFileExists(sb);
                }
                sw.Stop();
                sw.Dump("PathFileExists = false");
            
                sb = new StringBuilder(@"c:\Home\Temp\test.log");
                sw = Stopwatch.StartNew();
                for (int i = 0; i < 10000; i++)
                {
                    PathFileExists(sb);
                }
                sw.Stop();
                sw.Dump("PathFileExists = true");
            
            }
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-12-12
            • 1970-01-01
            • 1970-01-01
            • 2010-09-23
            • 2021-10-06
            • 2017-09-26
            • 1970-01-01
            相关资源
            最近更新 更多