我应该在调用File.Delete之前调用File.Exists吗?

我在finally子句中有一个File.Delete ,如下所示:

 finally { //remove the temporary file if(File.Exists(transformedFile)) File.Delete(transformedFile); } 

根据C#文档 ,在不存在的文件上调用File.Delete不会抛出任何exception。

是否可以删除包装的File.Exists ,还是会让我接触到可能的其他exception?

如果您需要它,它是不够的,因为在您确认它存在后可以删除该文件。 在这种情况下,最佳做法是简单地尝试删除该文件。 如果失败并显示“找不到文件”类型的错误,那么您将知道该文件不存在。 这将删除额外的操作并避免任何种类的竞赛窗口。

有一种情况是在Delete之前检查Exists可以防止exception。 如果文件名的路径无效,则Exists方法返回false

那么这取决于你想要的行为。 在某些情况下,无效路径应该导致exception。

另外,仅仅因为文件存在并不意味着它总是可以删除它(当时)。 您仍然需要针对不可预见的问题进行exception处理。

File.Delete不会抛出FileNotFoundException ,它并不关心。 它只会在路径无效时抛出exception,因为它有不存在的目录,在这种情况下它会抛出DirectoryNotFoundException

此代码不会抛出任何exception。

 var file = new FileInfo(@"C:\doesnotexist.file11111"); file.Delete(); 

这将抛出DirectoryNotFoundException

 var file = new FileInfo(@"C:\bad.dir\doesnotexist.file11111"); file.Delete(); 

MSDN File.Delete

让我们从逻辑和批判的角度看待这个问题。 假设MSDN doco不是100%准确(它确实包含偶然错误)并且可能抛出FileNotFoundException ,它将由以下两者引起:

  1. 该文件从未存在过(您退出了try并在创建文件之前输入了finally

  2. 你有程序错误(你已经错误地汇编了文件路径或名称)

人们会认为选项#2不应该发生,因为你测试了它,如果它仍然可以发生,那么你就会有臭臭的代码。 这使得选项#1成为唯一可行的选项,在这种情况下,您不关心exception,因此您只需捕获它并继续前进。 这意味着即使可能抛出FileNotFoundException,您的特定问题也基本上是多余的。

然而…
我仍然会使用try / catch包装File.Delete,因为IMVHO仍然有两个可能的exception,您需要注意: IOException和UnauthorizedAccessException 。 如果出现其中任何一种情况,您应该查看某种缓解措施(可能会在下次重新启动时将文件设置为删除和/或以某种方式通知用户)。

你仍然可以得到其他类型的例外。 例如IOException如果文件正在使用中。

因此,如果您坚持要删除finally块中的文件并希望确保不会出现exception,只需在File.delete周围放置另一个try-catch。

 finally { try { //remove the temporary file File.Delete(transformedFile); } catch { } } 

但如果您的目标是在任何情况下删除文件,我认为如果您专门打开文件将是个好主意,在这种情况下,您应首先关闭文件然后删除它。

我之前曾对这个问题提过类似的问题 ,我得出了这样的结论:

这取决于 。 是的,我知道……不是一个简单明了的答案,但是这里有一些注意事项可以确定你的情况是否需要存在文件检查和/或try { ... } catch { ... }阻止File.Delete(...)方法。

  • 你的代码是否生成了文件? 如果是这样,您实际上不需要检查文件是否存在。
  • 你是否关心处理其他问题? 请记住,您正在使用文件系统,并且MSDN文档清楚地向您显示该方法可能由于其他情况而生成exception。