为什么有时Directory.CreateDirectory失败?

时间:2016-01-28 18:33:12

标签: c#

这是我用来提取zip文件的代码,确保目标目录中没有任何脏文件

internal void UnzipProject()
{
    if (Directory.Exists(SourceDir))
        Directory.Delete(SourceDir, true);

    if (File.Exists(CodeZipFile))
    {
        Directory.CreateDirectory(SourceDir); // fails here
        ZipFile.ExtractToDirectory(CodeZipFile, SourceDir);
    }
}

有时候Directory.CreateDirectory(SourceDir)无法创建新的目录,我在下一行会遇到异常,但如果我退后一步重试dir创建,它就可以了。下次执行时会重复完全相同的模式。

修改
这是一个例外,实际上是关于dir没有被创建,我可以看到src dir不存在:

System.UnauthorizedAccessException was unhandled
  HResult=-2147024891
  Message=Access to the path '(...MyPath...)\src\MySolution.sln' is denied.
  Source=mscorlib
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
       at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
       at System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive source, String destinationDirectoryName)
       at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName, Encoding entryNameEncoding)
       at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName)
........

5 个答案:

答案 0 :(得分:10)

在Windows 7,.Net 4.0,VS2010下出现此问题。看起来Directory.Delete()不是同步的,所以问题是时间问题。我猜测Directory.CreateDirectory()没有失败,因为现有文件夹被标记为删除。然后在Directory.Delete()完成时删除新文件夹。

我发现这一点始终如一:

if (Directory.Exists(myPath))
  {
  Directory.Delete(myPath, true);
  while (Directory.Exists(myPath))
    System.Threading.Thread.Sleep(10);
  }

Directory.CreateDirectory(myPath);

答案 1 :(得分:4)

错误实际上已经在异常中。

System.UnauthorizedAccessException was unhandled

您需要添加代码来检查/验证用户是否有权访问该文件夹。

答案 2 :(得分:2)

谢谢大家帮我解决这个问题。问题是在调用删除后立即创建一个目录。在我的情况下删除的dir是空的,但可能是由于文件系统延迟,它在完全删除之前变得无法访问。我正在为面临同样问题的其他人分享解决方案:

internal void UnzipProject()
{
    if (Directory.Exists(SourceDir))
    {
        DirectoryInfo di = new DirectoryInfo(SourceDir);

        foreach (FileInfo file in di.GetFiles())
            file.Delete();

        foreach (DirectoryInfo dir in di.GetDirectories())
            dir.Delete(true);
    }

    if (File.Exists(zipFile))
        ZipFile.ExtractToDirectory(zipFile, SourceDir);

    else
    {
        if (Directory.Exists(SourceDir))
            Directory.Delete(SourceDir, true);
    }
}

答案 3 :(得分:0)

我的同事在频繁重写文件时遇到了这个错误。他告诉菲尔系统很慢。如果您遇到同样的问题,请尝试创建尚未删除的文件夹。

尝试在UnauthorizedAccessException上重复您的方法一次,或者\并在Directory.Delete之后添加Thread.Sleep(100)。

答案 4 :(得分:0)

我自己经历过这种行为。如果我没有弄错的话,会发生这种情况,因为Directory.Delete仍在尝试删除目录,同时Directory.CreateDirectory正在尝试重新创建它。 CreateDirectory将失败,因为系统仍然锁定了该资源以进行删除。

我通过在Delete调用和CreateDirectory调用之间引入了一点延迟来避免这个问题。我记得使用的另一个选项是重命名目录,然后删除它。例如,如果原始目录名为MyApp,我会将其重命名为DeleteMe,然后删除该目录。 CreateDirectory应该能够创建MyApp目录,因为它不再存在。