我使用。net 3.5,试图递归删除目录使用:

Directory.Delete(myPath, true);

我的理解是,如果文件正在使用或存在权限问题,这应该抛出,但否则它应该删除目录及其所有内容。

然而,我偶尔会遇到这样的情况:

System.IO.IOException: The directory is not empty.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
    at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
    ...

我并不惊讶于这个方法有时会抛出错误,但我惊讶于当递归为真时得到这个特定的消息。(我知道目录不是空的。)

是否有一个原因,我将看到这个而不是AccessViolationException?


当前回答

如果您的应用程序(或任何其他应用程序)的当前目录是您试图删除的目录,这将不是访问冲突错误,而是目录不是空的。 通过更改当前目录,确保它不是您自己的应用程序;同时,确保该目录没有在其他程序中打开(例如Word, excel, Total Commander等)。大多数程序将cd到最后打开的文件的目录,这将导致这种情况。

其他回答

编者注:尽管这个答案包含了一些有用的信息,但关于Directory.Delete的工作原理实际上是不正确的。请阅读这个答案的评论,以及这个问题的其他答案。


我以前遇到过这个问题。

The root of the problem is that this function does not delete files that are within the directory structure. So what you'll need to do is create a function that deletes all the files within the directory structure then all the directories before removing the directory itself. I know this goes against the second parameter but it's a much safer approach. In addition, you will probably want to remove READ-ONLY access attributes from the files right before you delete them. Otherwise that will raise an exception.

只需将这些代码放入您的项目中。

public static void DeleteDirectory(string target_dir)
{
    string[] files = Directory.GetFiles(target_dir);
    string[] dirs = Directory.GetDirectories(target_dir);

    foreach (string file in files)
    {
        File.SetAttributes(file, FileAttributes.Normal);
        File.Delete(file);
    }

    foreach (string dir in dirs)
    {
        DeleteDirectory(dir);
    }

    Directory.Delete(target_dir, false);
}

另外,对我个人来说,我对允许删除的机器区域添加了一个限制,因为你希望有人在C:\ windows (%WinDir%)或C:\。

目录或文件处于锁定状态,不能被删除。找到锁它的罪魁祸首,看看你是否能消除它。

我在使用TFS2012的构建服务器上使用Windows Workflow Foundation时遇到过同样的问题。在内部,工作流调用Directory.Delete()并将递归标志设置为true。在我们的案例中,这似乎与网络有关。

在用最新的二进制文件重新创建和重新填充网络共享上的二进制文件之前,我们正在删除它。其他的构建都会失败。在构建失败后打开删除文件夹时,文件夹为空,这表明directory. delete()调用的每个方面都是成功的,除了删除实际的目录。

这个问题似乎是由网络文件通信的异步特性引起的。构建服务器告诉文件服务器删除所有文件,文件服务器报告它已经删除了,即使它还没有完全完成。然后构建服务器请求删除目录,而文件服务器拒绝了该请求,因为它还没有完全完成文件的删除。

在我们的案例中有两个可能的解决方案:

在我们自己的代码中建立递归删除,每个步骤之间都有延迟和验证 在IOException发生后重试最多X次,在再次尝试之前给予延迟

后一种方法又快又脏,但似乎很管用。

对于网络文件,Directory.DeleteHelper(recursive:=true)可能会导致IOException,这是由于删除文件的延迟造成的

你是否可能有一个竞争条件,另一个线程或进程正在向目录中添加文件:

顺序是:

删除进程A:

清空目录 删除(现在是空的)目录。

如果其他人在1和2之间添加了一个文件,那么2可能会抛出列出的异常?