代码之家  ›  专栏  ›  技术社区  ›  JL. Hans Passant

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

  •  559
  • JL. Hans Passant  · 技术社区  · 15 年前

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

    29 回复  |  直到 6 年前
        1
  •  699
  •   Andrew Morton    6 年前
    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() ,因为当你使用 枚举文件() 您可以在返回整个集合之前开始枚举它,而不是 获取文件() 在开始枚举之前,需要将整个集合加载到内存中。看到这个报价 here :

    因此,当您处理许多文件和目录时,EnumerateFiles()可以更高效。

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

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

    就这个问题而言,确实没有理由使用 获取文件() 获取目录() .

        2
  •  164
  •   Adam Robinson    11 年前

    是的,这是正确的方法。如果你想给自己一个“干净”的(或者我更喜欢称之为“空”函数),你可以创建一个扩展方法。

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

    这样你就可以做……

    System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(@"C:\...");
    
    directory.Empty();
    
        3
  •  65
  •   Tshilidzi Mudau Simon Müller    8 年前

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

    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();
        }
    }
    
        4
  •  38
  •   Thulasiram    8 年前
     new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);
    
     //Or
    
     System.IO.Directory.Delete(@"C:\Temp", true);
    
        5
  •  37
  •   Peter Mortensen Sumit Kumar    9 年前

    我们也可以表现出对 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));
    

    请注意,这里的解决方案没有执行,因为我正在使用 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));
    

    这是扩展方法:

    /// <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);
            }
        }
    }
    
        6
  •  31
  •   Brian Webster    8 年前

    最简单的方法:

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

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

        7
  •  25
  •   zumalifeguard Arctic    6 年前

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

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

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

        Directory.GetFiles(folderName).ForEach(File.Delete)
    
        8
  •  12
  •   JustBeingHelpful    9 年前
    System.IO.Directory.Delete(installPath, true);
    System.IO.Directory.CreateDirectory(installPath);
    
        9
  •  6
  •   Alexandru Dicu    12 年前

    我尝试的每一种方法,都在某个时刻因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); 
    
        10
  •  6
  •   Peter Mortensen Sumit Kumar    9 年前

    下面的代码将清理目录,但将根目录留在那里(递归)。

    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);
    
        11
  •  4
  •   Community Jaime Torres    7 年前

    只对文件和目录使用静态方法,而不使用fileinfo和directoryinfo,执行速度更快。(见接受回答 What is the difference between File and FileInfo in C#? )答案显示为实用方法。

    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);
        }
    }
    
        12
  •  3
  •   Peter Mortensen Sumit Kumar    9 年前

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

    C:
      \AAA
        \BBB
          \CCC
            \DDD
    

    并运行原始问题中建议的代码来清理目录c:\aaa,行 di.Delete(true) 尝试删除bbb时总是失败,出现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);
        }
    }
    
        13
  •  3
  •   Mong Zhu Bart de Boer    8 年前
    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();
        }
    }
    
        14
  •  3
  •   Eric Bole-Feysot    6 年前

    这是我在阅读完所有文章后使用的工具。 它确实

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

    它处理

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

    它不使用目录。删除,因为进程因异常而中止。

        /// <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;
        }
    
        15
  •  2
  •   AVH    12 年前
    string directoryPath = "C:\Temp";
    Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
    Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
    
        16
  •  2
  •   Jeppe Andreasen    9 年前

    此版本不使用递归调用,并解决了只读问题。

    public static void EmptyDirectory(string directory)
    {
        // First delete all the files, making sure they are not readonly
        var stackA = new Stack<DirectoryInfo>();
        stackA.Push(new DirectoryInfo(directory));
    
        var stackB = new Stack<DirectoryInfo>();
        while (stackA.Any())
        {
            var dir = stackA.Pop();
            foreach (var file in dir.GetFiles())
            {
                file.IsReadOnly = false;
                file.Delete();
            }
            foreach (var subDir in dir.GetDirectories())
            {
                stackA.Push(subDir);
                stackB.Push(subDir);
            }
        }
    
        // Then delete the sub directories depth first
        while (stackB.Any())
        {
            stackB.Pop().Delete();
        }
    }
    
        17
  •  1
  •   Mr_Hmp    9 年前

    使用DirectoryInfo的GetDirectories方法。

    foreach (DirectoryInfo subDir in new DirectoryInfo(targetDir).GetDirectories())
                        subDir.Delete(true);
    
        18
  •  1
  •   Matt    8 年前

    下面的示例显示了如何做到这一点。它首先创建一些目录和文件,然后通过 Directory.Delete(topPath, true); :

        static void Main(string[] args)
        {
            string topPath = @"C:\NewDirectory";
            string subPath = @"C:\NewDirectory\NewSubDirectory";
    
            try
            {
                Directory.CreateDirectory(subPath);
    
                using (StreamWriter writer = File.CreateText(subPath + @"\example.txt"))
                {
                    writer.WriteLine("content added");
                }
    
                Directory.Delete(topPath, true);
    
                bool directoryExists = Directory.Exists(topPath);
    
                Console.WriteLine("top-level directory exists: " + directoryExists);
            }
            catch (Exception e)
            {
                Console.WriteLine("The process failed: {0}", e.Message);
            }
        }
    

    它是从 https://msdn.microsoft.com/en-us/library/fxeahc5f(v=vs.110).aspx .

        19
  •  1
  •   dsmyrnaios    8 年前

    这不是解决上述问题的最佳方法。但这是另一种选择…

    while (Directory.GetDirectories(dirpath).Length > 0)
     {
           //Delete all files in directory
           while (Directory.GetFiles(Directory.GetDirectories(dirpath)[0]).Length > 0)
           {
                File.Delete(Directory.GetFiles(dirpath)[0]);
           }
           Directory.Delete(Directory.GetDirectories(dirpath)[0]);
     }
    
        20
  •  0
  •   Entreco    11 年前
    DirectoryInfo Folder = new DirectoryInfo(Server.MapPath(path)); 
    if (Folder .Exists)
    {
        foreach (FileInfo fl in Folder .GetFiles())
        {
            fl.Delete();
        }
    
        Folder .Delete();
    }
    
        21
  •  0
  •   Diaa Eddin    10 年前
    using System;
    using System.IO;
    namespace DeleteFoldersAndFilesInDirectory
    {
         class Program
         {
              public static void DeleteAll(string path)
              {
                   string[] directories = Directory.GetDirectories(path);
                   string[] files = Directory.GetFiles(path);
                   foreach (string x in directories)
                        Directory.Delete(x, true);
                   foreach (string x in files)
                        File.Delete(x);
              }
              static void Main()
              {
                   Console.WriteLine("Enter The Directory:");
                   string directory = Console.ReadLine();
                   Console.WriteLine("Deleting all files and directories ...");
                   DeleteAll(directory);
                   Console.WriteLine("Deleted");
              }
         }
    }
    
        22
  •  0
  •   Robert Jay Mistry    9 年前

    这将显示我们如何删除文件夹并选中它。我们使用文本框

    using System.IO;
    namespace delete_the_folder
    {
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Deletebt_Click(object sender, EventArgs e)
        {
            //the  first you should write the folder place
            if (Pathfolder.Text=="")
            {
                MessageBox.Show("ples write the path of the folder");
                Pathfolder.Select();
                //return;
            }
    
            FileAttributes attr = File.GetAttributes(@Pathfolder.Text);
    
            if (attr.HasFlag(FileAttributes.Directory))
                MessageBox.Show("Its a directory");
            else
                MessageBox.Show("Its a file");
    
            string path = Pathfolder.Text;
            FileInfo myfileinf = new FileInfo(path);
            myfileinf.Delete();
    
        }
    
    
    }
    
    }
    
        23
  •  0
  •   Julian E.    9 年前
    using System.IO;
    
    string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
    
    foreach (string filePath in filePaths)
    
    File.Delete(filePath);
    
        24
  •  0
  •   Tshilidzi Mudau Simon Müller    8 年前

    主叫电话

    static void Main(string[] args)
    { 
       string Filepathe =<Your path>
       DeleteDirectory(System.IO.Directory.GetParent(Filepathe).FullName);              
    }
    

    添加此方法

    public static void DeleteDirectory(string path)
    {
        if (Directory.Exists(path))
        {
            //Delete all files from the Directory
            foreach (string file in Directory.GetFiles(path))
            {
                File.Delete(file);
            }
            //Delete all child Directories
            foreach (string directory in Directory.GetDirectories(path))
            {
                 DeleteDirectory(directory);
            }
            //Delete a Directory
            Directory.Delete(path);
        }
     }
    
        25
  •  0
  •   Tshilidzi Mudau Simon Müller    8 年前
     foreach (string file in System.IO.Directory.GetFiles(path))
     {
        System.IO.File.Delete(file);
     }
    
     foreach (string subDirectory in System.IO.Directory.GetDirectories(path))
     {
         System.IO.Directory.Delete(subDirectory,true); 
     } 
    
        26
  •  0
  •   Tshilidzi Mudau Simon Müller    8 年前

    要删除文件夹,这是使用文本框和按钮的代码 using System.IO; :

    private void Deletebt_Click(object sender, EventArgs e)
    {
        System.IO.DirectoryInfo myDirInfo = new DirectoryInfo(@"" + delete.Text);
    
        foreach (FileInfo file in myDirInfo.GetFiles())
        {
           file.Delete();
        }
        foreach (DirectoryInfo dir in myDirInfo.GetDirectories())
        {
           dir.Delete(true);
        }
    }
    
        27
  •  -2
  •   dadziu    10 年前
    private void ClearDirectory(string path)
    {
        if (Directory.Exists(path))//if folder exists
        {
            Directory.Delete(path, true);//recursive delete (all subdirs, files)
        }
        Directory.CreateDirectory(path);//creates empty directory
    }
    
        28
  •  -3
  •   LysanderM    11 年前

    你唯一应该做的就是 optional recursive parameter True .

    Directory.Delete("C:\MyDummyDirectory", True)

    多亏了.NET。:)

        29
  •  -4
  •   Anri dprahut    11 年前
    IO.Directory.Delete(HttpContext.Current.Server.MapPath(path), True)
    

    你不需要更多