文件.Exists方法会消耗大量资源吗?

4
那么,什么更好?使用这样的结构:

如何更好地使用这个结构:

if (File.Exist(fileName))
{
    // do something with file...
}

只是的。
try 
{
    // do something with file.
}
catch(Exception ex)
{
}

使用方法 File.Exist() 是否会很耗费资源?

谢谢!


3
"catch(FileNotFoundException ex)",是吧? - user743382
如果您有102%的把握文件将永远存在,那么您可以忽略检查。 - Sandeep
你肯定也应该问一下使用try/catch块的成本是多少?我被告知它们很昂贵,因此在可能的情况下应该避免使用。从这个角度来看,使用File.Exist。如果在处理文件时使用try catch更快,那么你可以假设他们已经以这种方式编写了File.Exist - Chris
  1. 如果你预计文件可能不存在,那么这种情况并不是异常情况,你应该使用File.Exists进行检查。
  2. 你需要多长时间才能编写一个简单的控制台应用程序来自己进行测量?这里有一个开始 for (int i = 0 ; i < 1000; i++){}。
- BenCr
File.Exists 永远不会抛出异常。 - leppie
5个回答

11

前者存在竞态条件:在您打开文件之前,另一个进程可能会删除该文件,尽管File.Exists已经返回true。而后者则不会出现这种情况。即使您事先检查了文件是否存在,如果您想忽略不存在的文件,仍然应该捕获异常。

因此,应该选择以下两种方式之一:

if (File.Exists(fileName))
{
    try
    {
        // ...
    }
    catch (FileNotFoundException)
    { }
}

或者

try
{
    // ...
}
catch (FileNotFoundException)
{ }

前者会重复检查,如果文件在网络共享上可能会很慢,后者会为非异常情况引发异常(被处理),使调试变得更加复杂。两者都有其优点。个人而言,我通常选择第二种,但任何一种都可以。


我认为微软出于这个原因已经从WinRT API中删除了执行File.Exists检查的功能。 - BenCr
在第一种情况下,当文件不存在时,您现在有两种可能性。如果在进入“if”块之前它不存在,那么您会怎么做?throw new FileNotFoundException() - CodeCaster
+1 记录经典的文件系统竞争条件。Mono 版本的 MSBuild 中到处都是这些问题... - leppie
@CodeCaster 有时候应该默默地忽略不存在的文件,我假设这个问题就是其中之一,因为问题中的代码就是这样做的(请注意catch块中没有任何内容)。所以如果在进入if块之前它不存在,File.Exists会返回false,然后跳过该块。没有问题。 - user743382
@CodeCaster 如果我们从不同的假设开始,那么我们会得出不同的结论。 :) 如果代码确实需要表明操作成功,就需要更多的东西。关于你提到的“但是还是”部分:正如我在答案中提到的,它会使调试变得复杂。对我来说,当抛出任何异常时停止很有用,而不仅仅是当抛出未处理的异常时。但这将导致大量已处理的异常。 - user743382
显示剩余4条评论

5

异常并不应该被用来处理应用程序的执行流程,避免异常是应该的,而不是期望它们成为执行流程中的正常部分。

对于99.999%的应用程序,如果有任何性能差异,都不会被注意到。如果文件应该存在但找不到属于异常情况,您可以使用try catch块,否则建议使用File.Exist方法。


“异常不应该被用来处理应用程序的流程,而是要避免异常的出现,并不要将其视为执行流程中的正常部分。” 我喜欢它。谢谢! - NoWar

1

这取决于您的程序流程和正在执行的操作。如果您“期望”文件存在,则可以依靠异常处理,因为如果文件不存在,则您的程序无法继续运行,并且异常很可能需要在调用链中更高层次上进行处理。

否则,如果涉及到像ReadFile()这样的方法,则会出现True|False|FileNotFound返回代码混乱。

使用File.Exists来“安全地”打开文件是相当无用的。考虑一下:

public String ReadFile(String filename)
{
    if (!File.Exists(filename))
    {
        // now what? throw new FileNotFoundException()? return null?
    }

    // Will throw FileNotFoundException if not exists, can happen (race condition, file gets deleted after the `if` above)
    using (var reader = new StreamReader(filename))
    {
        return reader.ReadToEnd();
    }
}

如果您想将数据附加到文件中,可以说您需要检查文件是否存在,但是StreamWriter构造函数有一个带有append参数的重载,它将允许编写器创建文件(如果不存在)并在其上附加(如果存在)。

因此,也许问题更好的表述应该是:什么样的有效用例需要使用File.Exists? 幸运的是,这个问题已经被问过并得到了回答


0

首先,我会检查文件是否存在,如果不存在就抛出异常。

之后,我会使用 try-catch 块来处理可能抛出的其他异常(如权限等)。

if (!File.Exist(fileName))
{
    throw new ArgumentException("filename");
    // or throw new FileNotFoundException("filename");
}


try 
{
    // do something with file.
}
catch(Exception ex)
{
}

0

第一个案例 -

if (File.Exist(fileName)) //A single statement to check and proceed. 

虽然后一种异常处理方法包括-

如果引发异常,则创建并传递给相应的catch块的异常类的对象

我更喜欢第一种方法,因为使用异常处理来处理执行流程不是一个好主意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接