我应该在调用 File.Delete 之前调用 File.Exists 吗?
Posted
技术标签:
【中文标题】我应该在调用 File.Delete 之前调用 File.Exists 吗?【英文标题】:Should I call File.Exists before calling File.Delete? 【发布时间】:2013-01-02 19:41:33 【问题描述】:我的 finally 子句中有一个File.Delete
,如下所示:
finally
//remove the temporary file
if(File.Exists(transformedFile))
File.Delete(transformedFile);
根据C# documentation,对不存在的文件调用 File.Delete 不会引发任何异常。
是否可以删除 File.Exists
包装,或者这会使我面临可能的其他异常?
【问题讨论】:
我之前问过的类似问题:***.com/questions/8823395/… @m-y 相似,但不重复 【参考方案1】:如果你需要它,它是不够的,因为文件可以在你确认它存在之后被删除。在这种情况下,最佳做法是简单地尝试删除文件。如果它因“找不到文件”类型的错误而失败,那么您将知道该文件不存在。这消除了额外的操作并避免了任何类型的竞争窗口。
【讨论】:
关于比赛条件的要点。这不应该在我的代码中发生,但我们都知道“不应该发生”的事情会发生什么。 对。竞争条件是不这样做的一般原因。它也只是不需要。 当然,在您调用 delete 后,该文件仍可能由其他人重新创建,因此您的其他代码可能仍存在竞争条件...【参考方案2】:在一种情况下,在Delete
之前检查Exists
可以防止异常。如果文件名的路径无效,Exists
方法将返回 false
。
那么这取决于你想要什么行为。在某些情况下,无效路径应该导致异常。
此外,仅仅因为文件存在并不意味着总是可以删除它(当时)。对于不可预见的问题,您仍然需要异常处理。
【讨论】:
我不太担心文件会留在那里,异常应该会冒泡到我们的日志记录层(另外,我真的不想在 finally 中尝试/捕获)。谢谢!【参考方案3】:File.Delete
不会抛出 FileNotFoundException
,它不在乎。
只有当路径无效时它才会抛出异常,因为它有不存在的目录,在这种情况下它会抛出DirectoryNotFoundException
。
这段代码不会抛出任何异常。
var file = new FileInfo(@"C:\doesnotexist.file11111");
file.Delete();
这将抛出DirectoryNotFoundException
var file = new FileInfo(@"C:\bad.dir\doesnotexist.file11111");
file.Delete();
MSDN File.Delete
【讨论】:
【参考方案4】:让我们从逻辑和批判的角度来看待这个问题。假设 MSDN doco 不是 100% 准确(它确实包含偶尔的错误)并且 FileNotFoundException 可能 被抛出,它可能由以下任一原因引起:
文件从一开始就不存在(您在创建文件之前退出了try
并输入了finally
)
您遇到了程序错误(您错误地组装了文件路径或名称)
人们会假设选项 #2 不应该发生,因为您对此进行了测试,如果它仍然可以发生,那么您的代码很臭。这使得选项 #1 作为唯一可行的选项,在这种情况下,您不关心异常,因此您只需抓住它并继续前进。这意味着即使可以抛出 FileNotFoundException,您的具体问题也基本上是多余的。
但是... 我仍然会用 try/catch 包装 File.Delete,因为 IMVHO 仍然存在两个可能的异常,您需要注意:IOException 和 UnauthorizedAccessException。如果发生其中任何一种情况,您应该考虑某种缓解措施(可能设置文件以在下次重新启动时删除和/或以某种方式通知用户)。
【讨论】:
虽然我不同意 MSDN 文档不是 100% 准确,但在这种情况下它是正确的。如果文件不存在,File.Delete() 不会抛出任何异常。 @m-y 是的,这是一种假设情况,但我正试图帮助 OP 自己分析这样的事情,分析思维是编程的关键部分。无论如何,所有其他答案(到目前为止)都集中在 FileNotFound 问题上,忘记了问题的第二部分......【参考方案5】:您仍然可以获得其他类型的异常。例如,如果文件正在使用,则出现 IOException。
因此,如果您坚持删除 finally 块中的文件并希望确保不会出现异常,只需在 File.delete 周围放置另一个 try-catch。
finally
try
//remove the temporary file
File.Delete(transformedFile);
catch
但如果您的目标是在任何情况下删除文件,我认为如果您以独占方式打开文件会是个好主意,在这种情况下您应该先关闭文件然后删除 它。
【讨论】:
【参考方案6】:我之前问过a similar question这个问题,我得出了这样的结论:
视情况而定。是的,我知道...这不是一个直接的答案,但这里有一些注意事项可以确定您的情况是否需要文件存在检查和/或 File.Delete(...)
方法周围的 try ... catch ...
块。
【讨论】:
是的,我可能希望其他异常只是冒泡,我不想抓住它们。以上是关于我应该在调用 File.Delete 之前调用 File.Exists 吗?的主要内容,如果未能解决你的问题,请参考以下文章
NSFetchedResultsController:在调用 -performFetch 之前,我是不是应该始终检查 fetchedObjects==nil?
根据行业惯例,我应该在进行 API 调用之前还是在 Alamofire 中进行 API 调用期间检查互联网可访问性
我应该在我自己的代码之后还是之前调用 [super superMethod]?
在调用 InternetGetProxyInfo() 之前应该进行哪些初始化?