C# 目录后的DirectoryNotFoundException.Exists

C# 目录后的DirectoryNotFoundException.Exists,c#,io,C#,Io,以下陈述如何解释: if (Directory.Exists(outputDestination) && new DirectoryInfo(outputDestination).GetFiles().Count() > 0) if (Directory.Exists(outputDestination) && new DirectoryInfo(outputDestination).GetFiles().Count() > 0)

以下陈述如何解释:

if (Directory.Exists(outputDestination) 
    && new DirectoryInfo(outputDestination).GetFiles().Count() > 0)
if (Directory.Exists(outputDestination) 
   && new DirectoryInfo(outputDestination).GetFiles().Count() > 0)
抛出一个
DirectoryNotFoundException
:在调用GetFiles()之前,如果I check目录存在,则找不到路径的一部分

以下陈述如何解释:

if (Directory.Exists(outputDestination) 
    && new DirectoryInfo(outputDestination).GetFiles().Count() > 0)
if (Directory.Exists(outputDestination) 
   && new DirectoryInfo(outputDestination).GetFiles().Count() > 0)
抛出DirectoryNotFoundException

您的代码可以抛出一个
DirectoryNotFoundException
,因为您已经创建了:

在软件开发中,检查时间到使用时间(TOCTOU或TOCTOU,发音为“tock too”)是一类软件错误,由检查条件(如安全凭证)和使用检查结果之间的系统变化引起。这是竞争条件的一个示例


仅仅因为目录存在是为了调用
directory.exists()
,这并不意味着它仍然存在是为了调用
DirectoryInfo()

为什么理论上它不能呢?@Fabjan发布的代码肯定会抛出一个
DirectoryNotFoundException
,因为它是TOCTU bug的完美例子。这几乎是一个与在中使用的C代码完全相同的C代码。在检查和使用之间的时间内,其他内容可以删除目录。事实上,诸如张贴代码之类的检查,在无用和误导之间的某个地方。FWIW我花了1分钟创建了一个示例程序,该程序在特定的if语句上由于特定的异常而崩溃,方法是强制出现竞争条件-@LasseVågsætherKarlsen我的意思是,对于OP提供的代码示例,在没有任何附加信息的情况下,它不应该抛出ex在大多数情况下避免所有“先检查后使用”代码的其他原因:检查不能与使用完全相同:检查不是使用。在本例中,目录可能存在,但当前用户可能无法读取其内容。通常,您只能通过一种方式优化此类代码,即检查负面条件,然后不执行其余操作,但对于正面条件,您实际上需要尝试实际代码,让它因异常而失败,并捕获这些异常。如果(!Directory.Exists(…))返回,则可以执行
但您不能保证以后尝试使用该文件夹时该文件夹存在,只能保证在您首次测试该文件夹时该文件夹存在。@LasseVågsætherKarlsen True。这将避免竞争条件,因为如果对象不存在,它将不会执行使用部分。不过,为了简单起见,我不建议进行这样的优化,除非有明显的性能影响。我完全同意这一点。还值得指出的是,在网络文件系统(或其他类似速度较慢的文件系统)上,
Directory.Exists()
优化通常是一种反优化,由于它需要在实际网络调用之前进行额外的网络调用,并且对于小目录,传输的数据量可能与实际网络调用相同。我在公司的代码中看到过很多情况,其中
Directory.Exists()
File.Exists()
检查使代码变慢,而不是变快。tl;dr:几乎在所有情况下,只捕获
目录NotFoundException
比预先检查要好得多。是的,这是由于asnycronous调用删除目录而导致的竞争条件。现在已标记为答案