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


当前回答

我在特尔斐也遇到过同样的问题。最终的结果是我自己的应用程序锁定了我想要删除的目录。不知何故,当我写入目录(一些临时文件)时,目录被锁定了。

问题在于,在删除它之前,我对它的父目录做了一个简单的更改。

其他回答

有一件重要的事情需要提一下(我把它作为注释添加了进去,但是不允许我这样做),那就是重载的行为从。net 3.5改变到了。net 4.0。

Directory.Delete(myPath, true);

从。net 4.0开始,它会删除文件夹中的文件,但在3.5中不会。在MSDN文档中也可以看到这一点。

net 4.0

删除指定的目录,如果指定,删除该目录中的任何子目录和文件。

net 3.5

删除一个空目录,如果指定,删除目录中的任何子目录和文件。

这个答案基于:https://stackoverflow.com/a/1703799/184528。与我的代码不同的是,我们只递归许多删除子目录和文件时,需要调用目录。第一次尝试删除失败(这可能是因为windows资源管理器查看目录)。

    public static void DeleteDirectory(string dir, bool secondAttempt = false)
    {
        // If this is a second try, we are going to manually 
        // delete the files and sub-directories. 
        if (secondAttempt)
        {
            // Interrupt the current thread to allow Explorer time to release a directory handle
            Thread.Sleep(0);

            // Delete any files in the directory 
            foreach (var f in Directory.GetFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
                File.Delete(f);

            // Try manually recursing and deleting sub-directories 
            foreach (var d in Directory.GetDirectories(dir))
                DeleteDirectory(d);

            // Now we try to delete the current directory
            Directory.Delete(dir, false);
            return;
        }

        try
        {
            // First attempt: use the standard MSDN approach.
            // This will throw an exception a directory is open in explorer
            Directory.Delete(dir, true);
        }
        catch (IOException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        }
        catch (UnauthorizedAccessException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        } 
    }

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

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方法,将删除包含文件的子文件和子文件夹。

在Windows资源管理器中选择路径或子文件夹似乎足以阻止目录的一次执行。Delete(path, true),抛出如上所述的IOException和死亡,而不是引导Windows资源管理器到父文件夹并按预期进行。

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

顺序是:

删除进程A:

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

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