【问题标题】:Should I generally use "if" or "try" when working with directories/files在处理目录/文件时,我通常应该使用“if”还是“try”
【发布时间】:2015-02-17 06:24:31
【问题描述】:

通常,当我使用文件和目录并想检查目录或文件的路径是否存在时,我只使用类似的东西:

if (Directory.Exists(path))
{
     //Something...
}

但是,如果我对this 的回答正确,建议允许仍然抛出异常,这意味着不要使用if,而是使用try.. catch

这是处理文件和目录时的通用方法,还是有时使用if(Directory.Exists... 或类似的东西更可取?

注意:在看到第一个响应后,只是想澄清某些目录/路径可能不存在的情况是预期的正常行为。

【问题讨论】:

  • 通常,您不希望异常成为正常执行流程的一部分。例如,您不希望通过将目录的路径传递给DirectoryInfo 来假设目录存在,捕获异常然后在抛出未找到目录的异常时创建它。
  • 恕我直言,异常代价高昂,通过代码验证数据的正确性并没有错。 [例如。您仍然可以将一个数字除以 0 并在异常情况下捕获它,但我觉得对数据进行完整性检查要好得多]。 SO专家可以发表更多评论..
  • 你总是不得不假设 IO 可能会导致异常。仅仅因为该目录在几毫秒之前存在并不意味着它现在仍然存在。这不太可能,但有可能。

标签: c# file directory


【解决方案1】:

您几乎总是必须在某个地方捕获异常,尤其是对于 I/O 错误,以免程序在发生时被简单地杀死。

在许多情况下,首先检查有效输入(例如Directory.Exists())是有意义的。这使您能够以用户友好的方式高效地报告和响应明显的用户错误场景。

但是您不能保证在执行该调用和尝试以某种方式访问​​它的时间之间不会删除该目录。或者,如果目录位于远程共享上,则网络不会出现故障。或者你不会有其他类型的 I/O 错误。

有一些例外是不值得捕捉的。例如,意外的OutOfMemoryException(与某些数据结构变得太大相反)或其他类型的内部 .NET 故障。从这些类型的错误中恢复的可能性很小。但是对于其他任何事情,您在某些时候应该捕获可能发生的异常。有时这仅仅意味着顶级catch (Exception e),您将在其中以某种方式记录异常,然后干净地退出程序。

(我会注意到,未捕获并导致应用程序终止的异常通常会记录在系统事件日志中。因此,只要用户能够轻松地检查日志并从那里检索异常信息,那么就没有需要捕获所有异常......只是那些你知道如何处理的)。

【讨论】:

  • 感谢您的回答。所以,你认为,我仍然应该使用try .. catch 机制,即使现有和不存在的文件/目录都是正常预期场景的一部分?
  • @EugeneS:是的,当然。特别是在你的代码执行依赖于你不能保证总是成功运行的外部组件的I/O场景中,你需要使用try/catch。当然 do 还包括对不存在的文件或目录的显式检查,特别是如果这是一个有效的场景,但即使它可能是一个错误,以使用户体验更好。但是这些检查并不能保护您的程序免受所有错误的影响。
【解决方案2】:

100% 取决于您想要达到的目标。

如果路径无效并且您想将其通知给用户,您可以选择返回成功值或根据更适合您的代码架构的方式抛出异常。

在其他情况下,如果出现问题而无需用户负责或无需通知用户,您通常会抛出异常并在适当位置的 catch 块中处理它们。

要记住的是,您始终可以执行if 检查并在无效状态的情况下抛出您自己的异常,而不是让无效状态自行引发异常。主要区别在于抛出异常的数据(堆栈跟踪、消息等),但也可以用性能表示(如果您可以先执行低成本操作,则您不会想尝试高成本操作检查以确保它会成功)。 Try-catch 块也会增加一点开销,但我认为这并不重要。

要问的问题是:

  • 无效状态是否会导致上面的整个操作失败?
  • 代码在哪里以及如何处理无效状态?
  • 代码是否“修复”了无效状态并重试?
  • 无效状态是源于用户错误还是代码问题?
  • 与验证检查的成本相比,操作的成本如何?

编辑:查看评论中 Yuval 的链接,以更好地了解 try-catch 块的成本。

验证检查的成本几乎总是很低,所以我总结说:执行检查,即使您打算在无效状态的情况下抛出自己的异常。

【讨论】:

  • Try-catch 块也会增加 BIT 的开销,但我认为这并不重要。 我会对此争论不休。异常的最大成本是堆栈展开。如果您深入使用递归方法并且由于堆栈顶部有catch 块而需要展开,那么您将付费。 This 对此有更多了解。
  • 感谢 Yuval,请参阅编辑。请注意,在许多情况下,异常是处理错误的更好、更合乎逻辑的方法,即使它们有代价。调用堆栈越大,成本越高 - 我通常以小框架方式处理异常。
  • 我完全赞成在正确的情况下使用异常。如果有不好的事情发生,扔掉。但是对于这个特定的用例,验证数据而不是依赖异常将是 IMO 更高效和“正确”的方法。
  • 我同意,在 OP 显示的情况下使用简单的 if 更有意义,并且根本不会抛出任何异常。我只是为手头的问题提供了一个完整的答案——try-catch vs if
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
相关资源
最近更新 更多