1

考虑这个简单的程序:

private static void Main(string[] args)
{
        var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

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

        Directory.CreateDirectory(directoryName);

        var stream = File.Create(Path.Combine(directoryName, "File")); //throws
        stream.Close();
}

当你简单地执行这个程序时,这很好用。Directory如果您在 Windows 资源管理器中浏览它然后运行,就会发生奇怪的事情。在这种情况下,我得到 UnautorizedAccessException"Access to the path 'C:\Users\rfurman\AppData\Roaming\Directory\File' is denied."

如果这很奇怪,那么在相同的条件下执行:

private static void Main(string[] args)
{
        var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

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

        var value = Directory.Exists(directoryName);

        Console.WriteLine(value);
        Console.ReadKey();
 }

该程序打印True是否Directory在资源管理器中打开。

我想知道的是为什么会发生这种情况以及如何防范这种情况。

我使用 Windows 7 和 .net 4。

4

4 回答 4

3

这有点重复: SSD驱动器上的奇怪目录删除行为

资源管理器只是导致文件夹删除的延迟稍长。删除目录不是“完全”同步操作。该目录被标记为删除,但实际删除可能会滞后一点。

AFAIK 这与 NTFS (win2k/Xp) 一样长。

于 2012-10-12T19:09:41.697 回答
2

Directory.Delete内部使用RemoveDirectorywin api 在Kernel32. RemoveDirectory 所做的是“标记要删除的目录”。当该目录的最后一个句柄关闭时,该目录被删除。我相信这意味着“在资源管理器离开该文件夹后”

在我的计算机中不会发生这种情况,所以我无法测试,但我怀疑可能有适合您的方法。基于 NT 的系统有时允许重命名文件和目录,即使它们是打开的。我不知道这是允许的确切情况,但我用它来重命名加载的 dll 文件并编写新的文件,如下所示:

File.Rename(@"C:\App\test.dll", @"C:\App\test.dll");
File.Copy(@"C:\App\Update\test.dll-v1.1", @"C:\App\test.dll");

所以你的代码在改变后可能看起来像这样

var directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Directory");

if (Directory.Exists(directoryName)) {
    var randomExt = ".random"; // generate randomly
    Directory.Move(directoryName, directoryName + randomExt)
    Directory.Delete(directoryName + randomExt, true);
}
Directory.CreateDirectory(directoryName);

var stream = File.Create(Path.Combine(directoryName, "File")); //throws
stream.Close();
于 2012-10-12T11:28:32.820 回答
0

这个问题也让我很惊讶。我的替代方案,这是一个不同的组合:

    if (Directory.Exists(directoryName))
    {
        Directory.Delete(directoryName, true);
        while (Directory.Exists(directoryName))
            Thread.Sleep(100);
    }

    Directory.CreateDirectory(directoryName);
于 2013-02-28T17:16:03.547 回答
-1

在某些情况下,如果您在文件资源管理器中打开了指定的目录,Delete 方法可能无法将其删除。

参考:Directory.Delete 方法

于 2012-10-09T11:15:51.660 回答