HOWTO · Csharp
在 C# 中删除一个目录中的所有文件
在 C# 中,可使用 FileInfo.Delete() 删除目录中直接包含的文件;若要递归删除目录及其内容,请对该目录调用 DirectoryInfo.Delete(true),这也会删除被调用的目录本身。
本页内容
若要删除目录中直接包含的所有文件,请枚举这些文件,并对每个文件调用 FileInfo.Delete()。这样会保留目标目录及其子目录。若还要删除子目录,其内容也会被递归删除,因此只有在确实需要时才选择这种做法。(C#;DirectoryInfo.Delete(true))(DirectoryInfo.Delete())
仅使用 DirectoryInfo.GetFiles() 删除文件
DirectoryInfo.GetFiles() 会返回一个 FileInfo 对象数组,其中包含目标目录直接包含的文件。对每个对象调用 FileInfo.Delete() 即可删除对应文件;此操作不会进入子目录。示例会创建专用的临时目标目录和示例文件,删除这些文件,并报告目标目录仍然存在。随后,清理过程会删除这个临时目标目录。
运行此示例。代码和输出保持原样,示例输出中的提示文字仍为英文:
using System;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "csharp-file-cleanup-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(path);
File.WriteAllText(Path.Combine(path, "first.txt"), "one");
File.WriteAllText(Path.Combine(path, "second.txt"), "two");
var directory = new DirectoryInfo(path);
int removed = 0;
foreach (FileInfo file in directory.GetFiles())
{
file.Delete();
removed++;
}
Console.WriteLine($"Files removed: {removed}");
Console.WriteLine($"Target directory remains: {directory.Exists}");
Directory.Delete(path);
}
}
Files removed: 2
Target directory remains: True
该路径位于操作系统的临时目录下。在应用程序代码中,请将路径设为预期位置,并确保进程有权限修改该位置。如果文件被锁定或访问遭拒,删除操作可能失败;请根据应用程序的需要处理相应的 I/O 或授权错误,不要假定每次调用都会成功。
使用 DirectoryInfo.GetDirectories() 删除文件和子目录
若要删除文件和子目录,请先删除目标目录直接包含的文件,再使用 DirectoryInfo.GetDirectories() 获取其中的子目录,并对每个子目录调用 DirectoryInfo.Delete(true)。参数 true 会递归删除该子目录及其内容。目标目录本身会保留。这是一项具有破坏性的操作:运行前请检查目标路径,并确认递归删除符合预期。
具体操作是先执行 foreach (FileInfo file in directory.GetFiles()) file.Delete();,再执行 foreach (DirectoryInfo child in directory.GetDirectories()) child.Delete(true);。请保持两个循环的顺序,并在程序中使用实际的目标 DirectoryInfo 实例。
使用 DirectoryInfo.EnumerateFiles() 删除文件
DirectoryInfo.EnumerateFiles() 会提供由 FileInfo 对象组成的可枚举序列,因此可以直接用于 foreach 循环。相比之下,GetFiles() 返回数组。两种方式都能删除目标目录直接包含的文件,也都不会删除子目录。可根据是否需要数组结果,或是否只需遍历序列来选择。对于所有工作负载,枚举都不保证一定能提升性能。
仅删除文件时,循环体仍是 file.Delete():
本节代码及其中显示的标签或输出保持原样,相关文字仍为英文。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "csharp-enumerate-files-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(path);
File.WriteAllText(Path.Combine(path, "sample.txt"), "content");
var directory = new DirectoryInfo(path);
foreach (FileInfo file in directory.EnumerateFiles())
{
file.Delete();
}
Console.WriteLine($"Files remaining: {directory.GetFiles().Length}");
Directory.Delete(path);
}
}
Files remaining: 0
代码和输出保持原样;输出提示文字仍为英文,并显示剩余文件数。
使用 DirectoryInfo.EnumerateDirectories() 删除子目录
DirectoryInfo.EnumerateDirectories() 会枚举目标目录中的子目录。若要删除某个子目录及其完整目录树,请对该子目录调用 Delete(true)。此操作不会删除直接位于目标目录中的文件;若两类内容都要删除,请将此操作与仅删除文件的循环结合使用。删除子目录后,目标目录仍会保留。
删除子目录的操作是 foreach (DirectoryInfo child in directory.EnumerateDirectories()) child.Delete(true);。除非确实需要递归删除,否则不要在仅清理文件的流程中加入这个循环。
选择合适的方法并验证结果
如果需要数组,请使用 GetFiles();如果要将文件结果作为可枚举序列处理,请使用 EnumerateFiles()。两者都只处理文件。只有在任务要求递归删除时,才添加调用 Delete(true) 的子目录循环。删除前请核实所选路径;删除后可使用 GetFiles() 和 GetDirectories() 检查目录内容。路径不存在或无法访问,或者文件无法删除,都可能导致操作未能完成。