如何删除目录中的所有文件和文件夹?
Posted
技术标签:
【中文标题】如何删除目录中的所有文件和文件夹?【英文标题】:How to delete all files and folders in a directory? 【发布时间】:2010-11-20 07:07:50 【问题描述】:使用 C#,如何删除目录中的所有文件和文件夹,但仍保留根目录?
【问题讨论】:
【参考方案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)
你不需要更多
【讨论】:
以上是关于如何删除目录中的所有文件和文件夹?的主要内容,如果未能解决你的问题,请参考以下文章