如何删除目录中的所有文件和文件夹?

JL.*_*JL. 621 .net c#

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

gsh*_*arp 777

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

foreach (FileInfo file in di.GetFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
    dir.Delete(true); 
}
Run Code Online (Sandbox Code Playgroud)

如果您的目录可能包含许多文件,EnumerateFiles()则效率更高GetFiles(),因为在您使用EnumerateFiles()时可以在返回整个集合之前开始枚举它,而不是GetFiles()在开始枚举之前需要在内存中加载整个集合的位置.在这里看到这个引用:

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

这同样适用于EnumerateDirectories()GetDirectories().所以代码是:

foreach (FileInfo file in di.EnumerateFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in di.EnumerateDirectories())
{
    dir.Delete(true); 
}
Run Code Online (Sandbox Code Playgroud)

出于这个问题的目的,没有理由使用GetFiles()GetDirectories().

  • DirectoryInfo很慢,因为这会收集更多其他数据.BTW:`Directory.Delete(path,true)`将照顾所有:) (68认同)
  • @AcidJunkie,这也将删除有问题的目录,而OP特别要求保留根目录. (50认同)
  • 如果子目录包含文件,这似乎不起作用. (7认同)
  • 什么是关于http://stackoverflow.com/questions/12415105/directory-is-not-empty-error-when-trying-to-programmatically-delete-a-folder"你打电话Directory.Delete和文件已打开在这样的方式,Directory.Delete成功地删除所有文件,但是当Directory.Delete调用RemoveDirectory一个"目录不为空"异常被抛出,因为有标记为删除但实际上没有删除的文件." (6认同)
  • @NotoriousPyro 用户希望保留根文件夹,这就是为什么两个 foreach (6认同)
  • 调用 file.Delete() 然后调用 dir.Delete(true) 是多余的,因为 dir.Delete(true) 会递归删除指定目录中的所有文件和文件夹。只需调用 di.Delete(true) 即可避免需要两个 foreach 循环:https://learn.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.delete?view=net-5.0#System_IO_DirectoryInfo_Delete_System_Boolean_ (5认同)
  • 请注意,如果任何文件是只读的,这将不起作用.在调用`file.Delete()`之前,需要删除只读标志. (4认同)
  • 用户没有提到他有打开文件的问题.所以它超出了这个问题的范围. (3认同)

Ada*_*son 169

是的,这是正确的方法.如果你想给自己一个"干净"(或者,我更喜欢称之为"清空"功能),你可以创建一个扩展方法.

public static void Empty(this System.IO.DirectoryInfo directory)
{
    foreach(System.IO.FileInfo file in directory.GetFiles()) file.Delete();
    foreach(System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
Run Code Online (Sandbox Code Playgroud)

这将允许你做类似的事情..

System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");

directory.Empty();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,对于`string`,C#中已经存在`Empty`.如果我看到其他名为"Empty"的东西,我会惊讶于它修改了对象(或文件系统)而不是给我一个`bool`来说明它是否为空.因此,我会选择"清洁"这个名字. (25认同)
  • @Default:我不认为一种类型具有属性的事实应该与另一种(完全不相关的)类型是否应该具有相关性; 表示状态也可以是动词的属性和函数的约定是用`Is`作为前缀(即`IsEmpty`而不是`Empty`). (5认同)
  • 最后一行应该是subDirectory.Delete(true)而不是directory.Delete(true).我只是剪切并粘贴了代码,它删除了主目录本身.感谢您的代码,这太棒了! (4认同)
  • @simonhaines:问题的关键是*清空目录(即删除其中的所有内容*),而不是删除目录本身. (4认同)
  • @AdamRobinson只是想记下来.对于*me*,微软在他们的代码中确实有一些影响.但它是每个人解释:) (3认同)

小智 70

以下代码将递归清除该文件夹:

private void clearFolder(string FolderName)
{
    DirectoryInfo dir = new DirectoryInfo(FolderName);

    foreach(FileInfo fi in dir.GetFiles())
    {
        fi.Delete();
    }

    foreach (DirectoryInfo di in dir.GetDirectories())
    {
        clearFolder(di.FullName);
        di.Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)


Thu*_*ram 38

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

 //Or

 System.IO.Directory.Delete(@"C:\Temp", true);
Run Code Online (Sandbox Code Playgroud)

  • 这将删除根目录,其中OP明确要求保留该目录. (13认同)
  • 如果目录不存在,则将删除`Delete`,因此先执行`Directory.Exists`检查会更安全。 (2认同)
  • @Marv小心地添加了一个`Directory.Create`因为递归的`Directory.Delete`不幸保证不是同步的. (2认同)

ras*_*asx 37

我们也可以表达对LINQ的热爱:

using System.IO;
using System.Linq;
…
var directory = Directory.GetParent(TestContext.TestDir);

directory.EnumerateFiles()
    .ToList().ForEach(f => f.Delete());

directory.EnumerateDirectories()
    .ToList().ForEach(d => d.Delete(true));
Run Code Online (Sandbox Code Playgroud)

请注意,我的解决方案不具备性能,因为我使用的Get*().ToList().ForEach(...)IEnumerable两次生成相同的解决方案.我使用扩展方法来避免此问题:

using System.IO;
using System.Linq;
…
var directory = Directory.GetParent(TestContext.TestDir);

directory.EnumerateFiles()
    .ForEachInEnumerable(f => f.Delete());

directory.EnumerateDirectories()
    .ForEachInEnumerable(d => d.Delete(true));
Run Code Online (Sandbox Code Playgroud)

这是扩展方法:

/// <summary>
/// Extensions for <see cref="System.Collections.Generic.IEnumerable"/>.
/// </summary>
public static class IEnumerableOfTExtensions
{
    /// <summary>
    /// Performs the <see cref="System.Action"/>
    /// on each item in the enumerable object.
    /// </summary>
    /// <typeparam name="TEnumerable">The type of the enumerable.</typeparam>
    /// <param name="enumerable">The enumerable.</param>
    /// <param name="action">The action.</param>
    /// <remarks>
    /// “I am philosophically opposed to providing such a method, for two reasons.
    /// …The first reason is that doing so violates the functional programming principles
    /// that all the other sequence operators are based upon. Clearly the sole purpose of a call
    /// to this method is to cause side effects.”
    /// —Eric Lippert, “foreach” vs “ForEach” [http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx]
    /// </remarks>
    public static void ForEachInEnumerable<TEnumerable>(this IEnumerable<TEnumerable> enumerable, Action<TEnumerable> action)
    {
        foreach (var item in enumerable)
        {
            action(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 34

最简单的方法:

Directory.Delete(path,true);  
Directory.CreateDirectory(path);
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,这将删除路径所具有的任何特殊权限 (9认同)
  • 您需要在这两个操作之间添加超时.尝试运行此代码,您将获得异常:while(true){Directory.Delete(@"C:\ Myfolder",true); Directory.CreateDirectory(@ "C:\ MyFolder文件"); } (4认同)

zum*_*ard 29

基于hiteshbiblog,您可能应该确保该文件是可读写的.

private void ClearFolder(string FolderName)
{
    DirectoryInfo dir = new DirectoryInfo(FolderName);

    foreach(FileInfo fi in dir.GetFiles())
    {
        try
        {
            fi.Delete();
        }
        catch(Exception) { } // Ignore all exceptions
    }

    foreach(DirectoryInfo di in dir.GetDirectories())
    {
        ClearFolder(di.FullName);
        try
        {
            di.Delete();
        }
        catch(Exception) { } // Ignore all exceptions
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你知道没有子文件夹,这样的东西可能是最简单的:

    Directory.GetFiles(folderName).ForEach(File.Delete)
Run Code Online (Sandbox Code Playgroud)


Mac*_*ver 12

System.IO.Directory.Delete(installPath, true);
System.IO.Directory.CreateDirectory(installPath);
Run Code Online (Sandbox Code Playgroud)

  • 与上面相同:请注意,这将删除路径所具有的任何特殊权限. (3认同)

Moh*_*ani 11

我用了

Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
Run Code Online (Sandbox Code Playgroud)

删除旧图片,我不需要此文件夹中的任何对象


小智 8

我知道这是一个古老的问题,但这是(也许是新的)正确答案:

new DirectoryInfo(folder).Delete(true);
Directory.CreateDirectory(folder);
Run Code Online (Sandbox Code Playgroud)

删除所有递归文件,然后重新创建文件夹。

PS-必须有参考using System.IO;

  • 这也会删除根目录,这不是问题所问的。 (4认同)
  • 如果根目录具有特定的 ACL 或其他 NTFS 配置,这可能会出现问题。 (2认同)

Ale*_*icu 7

我试过的每一种方法,都在System.IO错误的某些方面失败了.以下方法可以肯定,即使文件夹是空的,也可以是只读的,等等.

ProcessStartInfo Info = new ProcessStartInfo();  
Info.Arguments = "/C rd /s /q \"C:\\MyFolder"";  
Info.WindowStyle = ProcessWindowStyle.Hidden;  
Info.CreateNoWindow = true;  
Info.FileName = "cmd.exe";  
Process.Start(Info); 
Run Code Online (Sandbox Code Playgroud)

  • 这不是跨平台的解决方案.类Unix系统显然没有cmd.exe,它们甚至不运行.exe文件.C#不仅仅是Windows,还有Mono,它是跨平台的. (7认同)

小智 6

以下代码将清除目录,但保留根目录(递归).

Action<string> DelPath = null;
DelPath = p =>
{
    Directory.EnumerateFiles(p).ToList().ForEach(File.Delete);
    Directory.EnumerateDirectories(p).ToList().ForEach(DelPath);
    Directory.EnumerateDirectories(p).ToList().ForEach(Directory.Delete);
};
DelPath(path);
Run Code Online (Sandbox Code Playgroud)


Kri*_*iil 6

仅对 File 和 Directory 使用静态方法而不是 FileInfo 和 DirectoryInfo 会执行得更快。(请参阅C# 中 File 和 FileInfo 之间的区别是什么?)中接受的答案。答案显示为实用方法。

public static void Empty(string directory)
{
    foreach(string fileToDelete in System.IO.Directory.GetFiles(directory))
    {
        System.IO.File.Delete(fileToDelete);
    }
    foreach(string subDirectoryToDeleteToDelete in System.IO.Directory.GetDirectories(directory))
    {
        System.IO.Directory.Delete(subDirectoryToDeleteToDelete, true);
    }
}
Run Code Online (Sandbox Code Playgroud)


AVH*_*AVH 5

string directoryPath = "C:\Temp";
Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
Run Code Online (Sandbox Code Playgroud)


小智 5

private void ClearFolder(string FolderName)
{
    DirectoryInfo dir = new DirectoryInfo(FolderName);

    foreach (FileInfo fi in dir.GetFiles())
    {
        fi.IsReadOnly = false;
        fi.Delete();
    }

    foreach (DirectoryInfo di in dir.GetDirectories())
    {
        ClearFolder(di.FullName);
        di.Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*sot 5

这是我阅读所有帖子后使用的工具。确实

  • 删除所有可以删除的
  • 如果某些文件保留在文件夹中,则返回false

它处理

  • 只读文件
  • 删除延迟
  • 锁定文件

它不使用Directory.Delete,因为异常终止了该过程。

    /// <summary>
    /// Attempt to empty the folder. Return false if it fails (locked files...).
    /// </summary>
    /// <param name="pathName"></param>
    /// <returns>true on success</returns>
    public static bool EmptyFolder(string pathName)
    {
        bool errors = false;
        DirectoryInfo dir = new DirectoryInfo(pathName);

        foreach (FileInfo fi in dir.EnumerateFiles())
        {
            try
            {
                fi.IsReadOnly = false;
                fi.Delete();

                //Wait for the item to disapear (avoid 'dir not empty' error).
                while (fi.Exists)
                {
                    System.Threading.Thread.Sleep(10);
                    fi.Refresh();
                }
            }
            catch (IOException e)
            {
                Debug.WriteLine(e.Message);
                errors = true;
            }
        }

        foreach (DirectoryInfo di in dir.EnumerateDirectories())
        {
            try
            {
                EmptyFolder(di.FullName);
                di.Delete();

                //Wait for the item to disapear (avoid 'dir not empty' error).
                while (di.Exists)
                {
                    System.Threading.Thread.Sleep(10);
                    di.Refresh();
                }
            }
            catch (IOException e)
            {
                Debug.WriteLine(e.Message);
                errors = true;
            }
        }

        return !errors;
    }
Run Code Online (Sandbox Code Playgroud)