如何用Directory.EnumerateFiles()实现多扩展名文件搜索?
实现多扩展名文件搜索的几种方案
嘿,我懂你想实现的需求——不用重复调用Directory.EnumerateFiles,一次性搜索多个指定扩展名的同名文件对吧?可惜.NET原生的文件搜索方法并不支持.ext1||.ext2这种直接组合扩展名的语法,但咱们有几个简洁高效的办法来搞定这件事:
方法一:用LINQ合并多个单扩展名搜索结果
这是最直观的方案:先定义要搜索的扩展名列表,然后遍历每个扩展名执行搜索,最后用LINQ把所有结果合并成一个集合。
// 定义要搜索的扩展名(记得带点) var targetExtensions = new[] { ".ext1", ".ext2", ".ext3" }; // 获取目标文件名(不带扩展名) var baseFileName = Path.GetFileNameWithoutExtension(item); // 合并多个搜索结果 var matchingFiles = targetExtensions .Select(ext => Directory.EnumerateFiles(dir, $"{baseFileName}{ext}", SearchOption.AllDirectories)) .SelectMany(fileEnumerable => fileEnumerable);
这个方案的好处是延迟执行,不会一次性加载所有文件到内存,性能表现很友好,而且代码简洁易读。
方法二:先搜索所有同名文件,再过滤扩展名
如果你的场景中,同名但非目标扩展名的文件不多,也可以先搜索所有baseFileName.*的文件,再筛选出符合目标扩展名的结果:
// 用HashSet存储扩展名,提升后续过滤的查询效率 var targetExtensions = new HashSet<string> { ".ext1", ".ext2", ".ext3" }; var baseFileName = Path.GetFileNameWithoutExtension(item); var matchingFiles = Directory.EnumerateFiles(dir, $"{baseFileName}.*", SearchOption.AllDirectories) .Where(filePath => targetExtensions.Contains(Path.GetExtension(filePath)));
这种方式适合缩小初始搜索范围,但如果同名文件数量极大,可能不如第一种方法高效。
方法三:封装成扩展方法,方便复用
如果你的项目中经常需要这类多扩展名搜索,可以把逻辑封装成Directory的扩展方法,用起来和原生方法一样顺手:
public static class DirectoryExtensions { public static IEnumerable<string> EnumerateFilesWithMultipleExtensions( this string directoryPath, string fileNameWithoutExtension, IEnumerable<string> targetExtensions, SearchOption searchOption) { // 参数校验,避免空引用 if (string.IsNullOrEmpty(directoryPath)) throw new ArgumentNullException(nameof(directoryPath)); if (string.IsNullOrEmpty(fileNameWithoutExtension)) throw new ArgumentNullException(nameof(fileNameWithoutExtension)); if (targetExtensions == null) throw new ArgumentNullException(nameof(targetExtensions)); // 执行多扩展名搜索并合并结果 return targetExtensions .Select(ext => Directory.EnumerateFiles(directoryPath, $"{fileNameWithoutExtension}{ext}", searchOption)) .SelectMany(files => files); } }
调用的时候就像这样:
var targetExtensions = new[] { ".ext1", ".ext2", ".ext3" }; var matchingFiles = dir.EnumerateFilesWithMultipleExtensions( Path.GetFileNameWithoutExtension(item), targetExtensions, SearchOption.AllDirectories);
注意事项
- 所有扩展名记得带上英文点号(比如
.ext1而不是ext1),避免误匹配到类似fileext1.txt这类不符合要求的文件; - 如果需要确保结果中没有重复文件(虽然同一目录下同名同扩展名的文件不存在,但跨目录可能有特殊情况),可以在结果后追加
.Distinct(); - 两种LINQ方案都支持延迟执行,适合处理大量文件的场景,不会占用过多内存。
内容的提问来源于stack exchange,提问作者WpfBee
相关产品推荐
相关产品推荐

