【问题标题】:How to delete all files and folders in a directory?如何删除目录中的所有文件和文件夹?
【发布时间】:2010-11-20 07:07:50
【问题描述】:

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

【问题讨论】:

    标签: c# .net


    【解决方案1】:
    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() 效率更高,因为当你使用EnumerateFiles() 时,你可以在返回整个集合之前开始枚举它,而不是GetFiles() 你需要的地方在开始枚举之前将整个集合加载到内存中。看到这个引用here:

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

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

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

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

    【讨论】:

    • 调用 file.Delete() 然后 dir.Delete(true) 是多余的,因为 dir.Delete(true) 递归删除指定目录中的所有文件和文件夹。只需调用 di.Delete(true) 即可避免需要两个 foreach 循环:docs.microsoft.com/en-us/dotnet/api/…
    • @NotoriousPyro 用户希望保留根文件夹,这就是为什么两个 foreach
    【解决方案2】:

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

    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】:

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

      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】:

        最简单的方法:

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

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

        【讨论】:

          【解决方案5】:
           new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);
          
           //Or
          
           System.IO.Directory.Delete(@"C:\Temp", true);
          

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:
              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
                  }
              }
              

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

                  Array.ForEach(Directory.GetFiles(folderName), File.Delete);
              

              【讨论】:

                【解决方案8】:
                System.IO.Directory.Delete(installPath, true);
                System.IO.Directory.CreateDirectory(installPath);
                

                【讨论】:

                  【解决方案9】:

                  我用过

                  Directory.GetFiles(picturePath).ToList().ForEach(File.Delete);
                  

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

                  【讨论】:

                    【解决方案10】:

                    我尝试过的每一种方法,在某些时候都因 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); 
                    

                    【讨论】:

                      【解决方案11】:

                      这是我在阅读所有帖子后结束的工具。 会的

                      • 删除所有可以删除的内容
                      • 如果文件夹中保留一些文件,则返回 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;
                          }
                      

                      【讨论】:

                      • 好吧,今天我了解到不能以编程方式删除只读文件。但是,您的代码如何处理锁定的文件?它不只是跳过它们吗?
                      • @Arkane,我只是删除只读标志,删除文件并等待它从文件夹中消失。如果不是,我设置一个错误标志。
                      【解决方案12】:

                      仅对 File 和 Directory 使用静态方法而不是 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);
                          }
                      }
                      

                      【讨论】:

                        【解决方案13】:

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

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

                        【讨论】:

                          【解决方案14】:
                          string directoryPath = "C:\Temp";
                          Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);
                          Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
                          

                          【讨论】:

                            【解决方案15】:
                            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();
                                }
                            }
                            

                            【讨论】:

                              【解决方案16】:

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

                              C:
                                \AAA
                                  \BBB
                                    \CCC
                                      \DDD
                              

                              并运行原始问题中建议的代码以清理目录 C:\AAA,尝试删除 BBB 时,di.Delete(true) 行总是失败,并出现 IOException "The directory is not empty"。这可能是因为 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);
                                  }
                              }
                              

                              【讨论】:

                                【解决方案17】:

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

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

                                【讨论】:

                                  【解决方案18】:

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

                                  new DirectoryInfo(文件夹).Delete(true);

                                  【讨论】:

                                  • 这也删除了根目录,这不是问题要问的。
                                  【解决方案19】:

                                  以下示例显示了如何做到这一点。它首先创建一些目录和一个文件,然后通过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

                                  【讨论】:

                                    【解决方案20】:

                                    使用 DirectoryInfo 的 GetDirectories 方法。

                                    foreach (DirectoryInfo subDir in new DirectoryInfo(targetDir).GetDirectories())
                                                        subDir.Delete(true);
                                    

                                    【讨论】:

                                      【解决方案21】:

                                      这不是处理上述问题的最佳方法。但它是另一种选择......

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

                                      【讨论】:

                                        【解决方案22】:
                                        DirectoryInfo Folder = new DirectoryInfo(Server.MapPath(path)); 
                                        if (Folder .Exists)
                                        {
                                            foreach (FileInfo fl in Folder .GetFiles())
                                            {
                                                fl.Delete();
                                            }
                                        
                                            Folder .Delete();
                                        }
                                        

                                        【讨论】:

                                          【解决方案23】:
                                          using System.IO;
                                          
                                          string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
                                          
                                          foreach (string filePath in filePaths)
                                          
                                          File.Delete(filePath);
                                          

                                          【讨论】:

                                            【解决方案24】:

                                            从主调用

                                            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】:
                                               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】:

                                                要删除文件夹,这是使用文本框和按钮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】:

                                                  这将显示我们如何删除文件夹并使用文本框检查它

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

                                                  【讨论】:

                                                    【解决方案28】:
                                                    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
                                                    }
                                                    

                                                    【讨论】:

                                                      【解决方案29】:

                                                      您唯一应该做的就是将optional recursive parameter 设置为True

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

                                                      感谢 .NET。 :)

                                                      【讨论】:

                                                        【解决方案30】:
                                                        IO.Directory.Delete(HttpContext.Current.Server.MapPath(path), True)
                                                        

                                                        你不需要更多

                                                        【讨论】:

                                                          猜你喜欢
                                                          • 2010-11-12
                                                          • 1970-01-01
                                                          • 2019-11-21
                                                          • 2018-05-19
                                                          • 2011-10-13
                                                          • 1970-01-01
                                                          • 2020-12-22
                                                          • 1970-01-01
                                                          相关资源
                                                          最近更新 更多