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

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

814440 次浏览
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()则需要在开始枚举之前将整个集合加载到内存中。请参阅此引用这里

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

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

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

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

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

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

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

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

我们也可以表达对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);}}}
string directoryPath = "C:\Temp";Directory.GetFiles(directoryPath).ToList().ForEach(File.Delete);Directory.GetDirectories(directoryPath).ToList().ForEach(Directory.Delete);
 new System.IO.DirectoryInfo(@"C:\Temp").Delete(true);
//Or
System.IO.Directory.Delete(@"C:\Temp", true);

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

我尝试过的每个方法,它们都在某个时候失败了,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);
 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);}
DirectoryInfo Folder = new DirectoryInfo(Server.MapPath(path));if (Folder .Exists){foreach (FileInfo fl in Folder .GetFiles()){fl.Delete();}
Folder .Delete();}
IO.Directory.Delete(HttpContext.Current.Server.MapPath(path), True)

你不需要更多了

你唯一要做的就是将optional recursive parameter设置为True

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

感谢. NET.:)

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}

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

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

使用DirectoryInfo的GetDirectory方法。

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

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

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 placeif (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");elseMessageBox.Show("Its a file");
string path = Pathfolder.Text;FileInfo myfileinf = new FileInfo(path);myfileinf.Delete();
}

}
}

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

最简单的方法:

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

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

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

public static void EmptyDirectory(string directory){// First delete all the files, making sure they are not readonlyvar 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 firstwhile (stackB.Any()){stackB.Pop().Delete();}}
using System.IO;
string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
foreach (string filePath in filePaths)
File.Delete(filePath);

仅使用文件和目录的静态方法而不是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);}}
System.IO.Directory.Delete(installPath, true);System.IO.Directory.CreateDirectory(installPath);

从主呼叫

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 Directoryforeach (string file in Directory.GetFiles(path)){File.Delete(file);}//Delete all child Directoriesforeach (string directory in Directory.GetDirectories(path)){DeleteDirectory(directory);}//Delete a DirectoryDirectory.Delete(path);}}

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

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

while (Directory.GetDirectories(dirpath).Length > 0){//Delete all files in directorywhile (Directory.GetFiles(Directory.GetDirectories(dirpath)[0]).Length > 0){File.Delete(Directory.GetFiles(dirpath)[0]);}Directory.Delete(Directory.GetDirectories(dirpath)[0]);}
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();}}

这是我读完所有帖子后结束的工具。确实如此

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

我用

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

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

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

new DirectoryInfo(folder).Delete(true);Directory.CreateDirectory(folder);

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

PS-必须有引用using System.IO;

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

在我的情况下

var PhotoFile = _context.Records.Where(x => id_or_ids.Contains(x.Id)).Select(x => x.Photo).ToList();
System.IO.DirectoryInfo di = new DirectoryInfo("wwwroot/uploads");
foreach (FileInfo file in di.GetFiles()){if (PhotoFile.IndexOf(file.Name) != -1){file.Delete();}}