使用C#,如何删除目录中的所有文件和文件夹,但仍然保留根目录?


当前回答

在Windows 7中,如果您刚刚使用Windows资源管理器手动创建了它,则目录结构与以下类似:

C:
  \AAA
    \BBB
      \CCC
        \DDD

运行原始问题中建议的代码来清理目录C:\AAA,当尝试删除BBB时,行di.Delete(true)总是失败,并出现IOException“目录不是空的”。这可能是由于Windows资源管理器中的某种延迟/缓存。

以下代码对我来说工作可靠:

static void Main(string[] args)
{
    DirectoryInfo di = new DirectoryInfo(@"c:\aaa");
    CleanDirectory(di);
}

private static void CleanDirectory(DirectoryInfo di)
{
    if (di == null)
        return;

    foreach (FileSystemInfo fsEntry in di.GetFileSystemInfos())
    {
        CleanDirectory(fsEntry as DirectoryInfo);
        fsEntry.Delete();
    }
    WaitForDirectoryToBecomeEmpty(di);
}

private static void WaitForDirectoryToBecomeEmpty(DirectoryInfo di)
{
    for (int i = 0; i < 5; i++)
    {
        if (di.GetFileSystemInfos().Length == 0)
            return;
        Console.WriteLine(di.FullName + i);
        Thread.Sleep(50 * i);
    }
}

其他回答

最简单的方法:

Directory.Delete(path,true);  
Directory.CreateDirectory(path);

请注意,这可能会删除文件夹上的某些权限。

System.IO.DirectoryInfo di = new DirectoryInfo("YourPath");

foreach (FileInfo file in di.GetFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
    dir.Delete(true); 
}

如果您的目录可能有许多文件,EnumerateFiles()比GetFiles()更有效,因为当您使用EnumerateFile()时,您可以在返回整个集合之前开始枚举它,而不是GetFiles(,在开始枚举之前,您需要在内存中加载整个集合。请参阅此处的引用:

因此,当您使用许多文件和目录时,EnumerateFiles()可以更有效。

这同样适用于EnumerateDirectories()和GetDirectory()。所以代码应该是:

foreach (FileInfo file in di.EnumerateFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
    dir.Delete(true); 
}

对于这个问题,确实没有理由使用GetFiles()和GetDirectories()。

 new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);

 //Or

 System.IO.Directory.Delete(@"C:\Temp", true);
using System.IO;

string[] filePaths = Directory.GetFiles(@"c:\MyDir\");

foreach (string filePath in filePaths)

File.Delete(filePath);

DirectoryInfo.GetFileSystemInfos同时返回文件和目录:-

new DirectoryInfo(targetDir).GetFileSystemInfos().ToList().ForEach(x => x.Delete());

或者如果要递归删除:-

        new DirectoryInfo(targetDir).GetFileSystemInfos().ToList().ForEach(x =>
        {
            if (x is DirectoryInfo di)
                di.Delete(true);
            else
                x.Delete();
        });