【问题标题】:C# CreateDirectory behaving strange - Not creating directoryC# CreateDirectory 行为奇怪 - 不创建目录
【发布时间】:2016-10-12 19:51:28
【问题描述】:

我将删除一个目录(如果存在),然后重新创建该目录。

我的代码是这样的:

                if (Directory.Exists(destFolder))
                {
                    Directory.Delete(destFolder, true);
                    DirectoryInfo dirInfo = Directory.CreateDirectory(destFolder);
                }
                else
                {
                    Directory.CreateDirectory(destFolder);
                }

我面临的问题是:如果目录已经包含文件并且该目录当前在 Windows 资源管理器窗口之一中打开(即使任何应用程序中都没有打开文件),那么:

  1. Directory.Delete 删除目录,资源管理器窗口自动导航到父文件夹。
  2. CreateDirectory 不会抛出任何错误,但它返回的 DirectoryInfo 包含 Exists 为 false。

因此,稍后在我的程序中,当我尝试在该目录中创建文件时,出现错误:“找不到路径的一部分”

为什么会出现这种行为以及解决方案是什么?

谢谢。

编辑 1: 有时 DirectoryInfo.Exists 返回 true,但目录实际上并不存在于资源管理器中!

【问题讨论】:

  • 在我的测试中 Directory.Exist 和 DirectoryInfo.Exist 在删除并重新创建后返回 true。
  • 检查我上面的编辑。即使 Exists = true,您能否验证 Directory 是否确实已创建?您是否确保该目录有文件,并且该目录已在资源管理器窗口之一中打开?
  • 我之前放了Thread.Sleep(100),效果很好。
  • 此文件夹是否有只读文件?
  • 很多程序都喜欢打开目录的句柄。最常见的原因是这样的程序使用了 FileSystemWatcher 的等价物(就像 Explorer 一样)。或者因为目录是程序的Environment.CurrentDirectory。该句柄以 FileShare.Delete 的等效项打开。换句话说,删除工作正常,但在所有句柄关闭之前它实际上不会消失。后一个子句是问题所在, CreateDirectory() 在此之前无法成功。这需要多长时间是完全无法预测的。您可以重命名该目录或将其移至回收站。

标签: c# file-io


【解决方案1】:

文件系统操作不是同步的。

RemoveDirectory 函数将目录标记为在关闭时删除。因此,在关闭该目录的最后一个句柄之前,不会删除该目录。 如您所见,在关闭目录的所有句柄之前,它不会真正删除目录,但Directory.DeleteDirectory 会很好地完成。在您的情况下,这也很可能是此类并发问题 - 在您执行 Directory.Exists 时并未真正创建目录。所以你也可以在你的情况下使用 RemoveDirectory 函数。

或者如果你想使用Thread.Sleep(),你可以使用代码定期检查它。

            if (Directory.Exists(destFolder))
            {
                Directory.Delete(destFolder, true);     
                Thread.Sleep(1000);
                DirectoryInfo dirInfo = Directory.CreateDirectory(destFolder);
            }
            else
            {
                Directory.CreateDirectory(destFolder);
            }

另一种解决方案:

if (Directory.Exists(destFolder))
        {
            DirectoryInfo di = new DirectoryInfo(destFolder);

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

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

            DirectoryInfo dirInfo = Directory.CreateDirectory(destFolder);

        }

【讨论】:

  • 好的。我会接受这一点,除非我在不使用 Thread.Sleep 的情况下获得任何其他替代解决方案
  • @viveknuna,好的两种方法。
【解决方案2】:

由于您要求提供类似于 vivek nuna 的不使用 Thread.Sleep 的解决方案:

您还可以使用 FileSystemWatcher 来监视目录的删除。在正常情况下,这应该比 Thread.Sleep 更快。

但是,如果您采用这条路线,还可以设置一个计时器并检查目录是否在您不被告知的情况下消失了。当托管驱动器的系统不支持通知时,FileSystemWatcher 会静默失败。

【讨论】:

    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多