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


当前回答

当方法是异步的并像这样编码时,我解决了上述问题的一个可能实例:

// delete any existing update content folder for this update
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
       await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

用这个:

bool exists = false;                
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
    exists = true;

// delete any existing update content folder for this update
if (exists)
    await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

结论?去除用于检查存在的句柄有一些异步的方面,微软无法与之对话。这就好像if语句中的异步方法让if语句充当using语句一样。

其他回答

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

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

在Windows上,当目录(或任何子目录)中的文件路径长度大于260个符号时,就会出现此问题。

在这种情况下,您需要删除\\\\?\C:\mydir而不是C:\mydir。 大约260个符号的限制,你可以在这里阅读。

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

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);
        } 
    }

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

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