如何避免在File.Exists / File.Delete或Directory.Exists / Directory.Delete中进行竞争

时间:2015-01-30 17:32:12

标签: .net file-io

if (Directory.Exists(dir))
    Directory.Delete(dir, true);

上面的代码检查目录是否存在,如果存在,则删除它。在存在检查和删除之间存在添加或删除目录的可能性。

除了调用。删除并抛弃异常外,还有一种正确的方法来阻止这种竞争条件吗?

编辑:

避免与异常处理对抗竞争条件的原因是exceptions should not be used for control flow.

理想的解决方案是某种文件系统锁?

3 个答案:

答案 0 :(得分:3)

您可以做的最好的事情是Directory.Exists和异常处理之间的混合

if (Directory.Exists(dir))
{
    try 
    {
        Directory.Delete(dir, true);
    }
    catch (DirectoryNotFoundException e)
    {
        // do nothing, it means it doesn't exist
    }
}

为什么不尝试一下?因为异常不应该用于处理应用程序流。您尝试使用if语句来避免异常,但是在角落情况下它会发生,您可以处理它。

答案 1 :(得分:3)

如果所需的最终结果是确保目录dir不存在,无论它是否存在,那么您应该致电Directory.Delete 并捕获它可能抛出的任何异常,而无需检查目录是否存在。然后你应该检查目录是否存在,看你是否适合去,或者你的操作是否由于其他原因而失败:

try {
    Directory.Delete(dir, true);
} catch {
    // Ignore any exceptions
}
if (Directory.Exists(dir)) {
    // The above has failed to delete the directory.
    // This is the situation to which your program probably wants to react.
}

答案 2 :(得分:1)

您的代码是唯一可以删除或添加此类文件夹的内容吗? 如果是这样,为什么不将关键部分添加到代码中,例如object单例和lock结构?

如果您想避免删除已删除的文件夹,可以为其添加进程handle,以便其他进程无法销毁它。

如果您想避免此代码无法删除所需目录的情况,我无法想象这是一个很好的解决方案。想象一下情况:你的代码运行,完成后,有人重新创建文件夹。

为什么不在这种情况下捕获特定的异常?它是.NET中处理意外情况的自然方式。有一个lot of situations you can't predict

  

<强>例外

     

IOException
  存在由path指定的具有相同名称和位置的文件。    - 或 -
  path指定的目录是只读的,或者递归为false,path不是空目录。    - 或 -
  该目录是应用程序的当前工作目录。    - 或 -
  该目录包含只读文件。    - 或 -
  该目录正由另一个进程使用。

     

UnauthorizedAccessException
  呼叫者没有所需的权限。

     

ArgumentException
  path是一个零长度字符串,包含   仅限空格,或包含一个或多个无效字符。您可以   使用GetInvalidPathChars方法查询无效字符。

     

ArgumentNullException   path为null。

     

PathTooLongException
  指定的路径,文件名或两者都超过系统定义的最大值   长度。例如,在基于Windows的平台上,路径必须更少   比248个字符和文件名必须少于260个字符。

     

DirectoryNotFoundException
  路径不存在或无法找到。    - 或 -
  指定的路径无效(例如,它位于未映射的驱动器上)。