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


当前回答

这个答案基于: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);
        } 
    }

其他回答

我花了几个小时来解决这个问题和删除目录的其他异常。 这就是我的解

 public static void DeleteDirectory(string target_dir)
    {
        DeleteDirectoryFiles(target_dir);
        while (Directory.Exists(target_dir))
        {
            lock (_lock)
            {
                DeleteDirectoryDirs(target_dir);
            }
        }
    }

    private static void DeleteDirectoryDirs(string target_dir)
    {
        System.Threading.Thread.Sleep(100);

        if (Directory.Exists(target_dir))
        {

            string[] dirs = Directory.GetDirectories(target_dir);

            if (dirs.Length == 0)
                Directory.Delete(target_dir, false);
            else
                foreach (string dir in dirs)
                    DeleteDirectoryDirs(dir);
        }
    }

    private static void DeleteDirectoryFiles(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)
        {
            DeleteDirectoryFiles(dir);
        }
    }

这段代码有很小的延迟,这对我的应用程序并不重要。但是要注意,如果要删除的目录中有很多子目录,那么延迟可能会成为一个问题。

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

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

不删除文件的递归目录删除当然是意外的。我的解决办法是:

public class IOUtils
{
    public static void DeleteDirectory(string directory)
    {
        Directory.GetFiles(directory, "*", SearchOption.AllDirectories).ForEach(File.Delete);
        Directory.Delete(directory, true);
    }
}

我经历过这样做有帮助的案例,但一般来说,Directory。Delete在递归删除时删除目录中的文件,如msdn中所述。

作为Windows资源管理器的用户,我偶尔也会遇到这种不正常的行为:有时我无法删除文件夹(它认为荒谬的消息是“拒绝访问”),但当我向下钻取并删除较低的项目时,我也可以删除上面的项目。所以我猜上面的代码处理的是操作系统异常——而不是基类库问题。

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

这个答案基于: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);
        } 
    }