我使用。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?


当前回答

你不必创建一个额外的递归方法或删除额外文件夹内的文件。这些都是通过调用自动完成的

DirectoryInfo.Delete ();

详情在这里。

像这样的东西效果很好:

  var directoryInfo = new DirectoryInfo("My directory path");
    // Delete all files from app data directory.

    foreach (var subDirectory in directoryInfo.GetDirectories())
    {
          subDirectory.Delete(true);// true set recursive paramter, when it is true delete sub file and sub folder with files too
    }

将true作为变量传递给delete方法,将删除包含文件的子文件和子文件夹。

其他回答

编者注:尽管这个答案包含了一些有用的信息,但关于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:\。

我有那些奇怪的权限问题删除用户配置文件目录(在C:\文档和设置),尽管能够这样做在资源管理器外壳。

File.SetAttributes(target_dir, FileAttributes.Normal);
Directory.Delete(target_dir, false);

对我来说,“文件”操作在目录上做什么毫无意义,但我知道它可以工作,这对我来说就足够了!

这是因为FileChangesNotifications。

它发生在ASP。NET 2.0。当你删除应用程序中的某个文件夹时,它会重新启动。你可以自己看,用 ASP。NET运行状况监视。

只需将这段代码添加到你的web.config/configuration/system.web:

<healthMonitoring enabled="true">
  <rules>
    <add name="MyAppLogEvents" eventName="Application Lifetime Events" provider="EventLogProvider" profile="Critical"/>
  </rules>
</healthMonitoring>

之后,检查Windows Log ->应用程序。 发生了什么:

删除文件夹时,如果有子文件夹,delete (path, true)会先删除子文件夹。这足以让FileChangesMonitor知道删除和关闭你的应用程序。同时你的主目录还没有删除。这是来自日志的事件:

Delete()没有完成它的工作,因为应用程序正在关闭,它引发了一个异常:

当你正在删除的文件夹中没有任何子文件夹时,Delete()只是删除所有文件和该文件夹,app也会重新启动,但你不会得到任何异常,因为app重新启动不会中断任何事情。但是,你仍然会失去所有进程中的会话,应用程序在重新启动时不响应请求,等等。

现在该做什么?

There are some workarounds and tweaks to disable this behaviour, Directory Junction, Turning Off FCN with Registry, Stopping FileChangesMonitor using Reflection (since there is no exposed method), but they all don't seem to be right, because FCN is there for a reason. It is looking after structure of your app, which is not structure of your data. Short answer is: place folders you want to delete outside of your app. FileChangesMonitor will get no notifications and your app will not be restarted every time. You will get no exceptions. To get them visible from the web there are two ways:

创建一个控制器来处理传入调用,然后通过从应用程序外部(wwwroot外部)的文件夹读取文件返回。 如果你的项目很大,性能是最重要的,那就单独设置一个小型快速的web服务器来提供静态内容。因此,您将把他的具体工作留给IIS。它可以在同一台机器上(Windows的mongoose),也可以在另一台机器上(Linux的nginx)。好消息是你不需要支付额外的微软许可证来在linux上设置静态内容服务器。

希望这能有所帮助。

我今天遇到了这个问题。这是因为我有windows资源管理器打开目录,试图删除,导致递归调用失败,从而IOException。确保没有打开该目录的句柄。

此外,MSDN明确表示,您不必编写自己的回避:http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx

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

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

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

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

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

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