Directory.GetFiles 一次性获取所有文件路径
最直接的方式是用
Directory.GetFiles,它返回
string[],包含匹配条件的完整文件路径。默认不递归,只查当前目录:
string[] files = Directory.GetFiles(@"C:\MyFolder");
加第三个参数可递归搜索:
SearchOption.AllDirectories;用第二个参数可过滤扩展名,比如
"*.txt"。 注意:如果目录不存在或无权限,会直接抛
DirectoryNotFoundException或
UnauthorizedAccessException,不能靠返回空数组判断失败 大目录下容易内存暴涨——所有路径一次性加载进内存,不用
foreach遍历时也已分配完毕 不支持按修改时间、大小等动态条件筛选,纯字符串匹配
Directory.EnumerateFiles 更适合逐个处理大目录
当文件数多、或只需遍历处理(如日志扫描、批量重命名),优先选
Directory.EnumerateFiles。它返回
IEnumerable<string></string>,边枚举边 yield,内存占用低:
foreach (string file in Directory.EnumerateFiles(@"C:\Logs", "*.log", SearchOption.AllDirectories))
{
Console.WriteLine(file);
// 处理单个文件,不会提前加载全部路径
}
遇到权限不足的子目录时,默认跳过(不抛异常),但可通过 try/catch捕获
UnauthorizedAccessException并继续 不支持通配符组合(如
"a*.log|b*.txt"),一次只能传一个模式 返回路径格式依赖输入路径写法:若输入相对路径,结果也是相对路径;建议统一用绝对路径避免歧义
用 DirectoryInfo + GetFiles 需要手动处理递归和异常
DirectoryInfo提供面向对象接口,
GetFiles()方法行为类似
Directory.GetFiles,但允许复用实例、检查属性(如
Parent、
Exists):
var dir = new DirectoryInfo(@"C:\Data");
if (!dir.Exists) return;
FileInfo[] files = dir.GetFiles("*.config");
递归需手动实现:调用 GetDirectories()后逐层
GetFiles(),比
SearchOption.AllDirectories冗长且易漏异常处理 每个
FileInfo实例带文件元数据(
LastWriteTime、
Length等),适合需要属性再过滤的场景,但创建开销比纯路径字符串大 对符号链接(symlink)或挂载点行为不透明,Windows 上可能意外跳入其他卷,需额外校验
FullName.StartsWith(dir.FullName)
跨平台注意:.NET Core/.NET 5+ 的路径分隔符与大小写敏感性
在 Linux/macOS 上,
Directory.GetFiles和
EnumerateFiles默认区分大小写,且只认正斜杠
/或系统原生分隔符(
Path.DirectorySeparatorChar)。硬写反斜杠
\在非 Windows 平台可能静默失败或返回空: 始终用
Path.Combine("folder", "sub") 拼路径,别手拼字符串
过滤时若需忽略大小写,得自己用 StringComparer.OrdinalIgnoreCase做二次筛选,API 不提供该选项 Docker 容器内挂载 Windows 主机目录时,路径大小写行为取决于挂载方式(如
case-sensitive: false),实测可能和本地 Linux 表现不一致 实际项目里,多数情况直接用
Directory.EnumerateFiles加
try/catch处理权限异常就够了。真要按时间范围筛选,别硬塞在枚举里,先取路径再用
FileInfo读属性——顺序错了,性能就崩了。
