c# - 高效检索和过滤文件

标签 c# linq performance file

earlier SO question讨论如何检索目录树中与多个扩展名之一匹配的所有文件。

例如。检索 C:\和所有子目录中的所有文件,匹配 *.log、*.txt、*.dat。

接受的答案是这样的:

var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

这让我觉得效率很低。如果您在包含数千个文件的目录树上搜索(它使用 SearchOption.AllDirectories),指定目录树中的每个文件都会加载到内存中,然后才会删除不匹配的文件。 (让我想起 ASP.NET 数据网格提供的“分页”。)

不幸的是,标准的 System.IO.DirectoryInfo.GetFiles 方法一次只接受一个过滤器。

这可能只是我缺乏 Linq 知识,我提到的方式实际上是低效的吗?

其次,是否有一种更有效的方法来实现无论是否使用 Linq(无需多次调用 GetFiles)?

最佳答案

我分享了您的问题,并在 Matthew Podwysocki 的 excellent post 中找到了解决方案在 codebetter.com .

他使用 native 方法实现了一个解决方案,允许您在他的 GetFiles 实现中提供谓词。此外,他使用 yield 语句实现了他的解决方案,有效地将每个文件的内存使用率降至最低。

用他的代码你可以写出类似下面的东西:

var allowedExtensions = new HashSet<string> { ".jpg", ".mp3" };

var files = GetFiles(
    "C:\\path", 
    SearchOption.AllDirectories, 
    fn => allowedExtensions.Contains(Path.GetExtension(fn))
);

并且 files 变量将指向一个枚举器,该枚举器返回匹配的文件(延迟执行样式)。

关于c# - 高效检索和过滤文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/541181/

相关文章:

c# - "T @this"在委托(delegate)声明中是什么意思?

c# - selectmany + join + let 的 LINQ 查询语法

android - 使用 android Picasso 或 Glide 滚动时出现卡顿效果

c# - Batchify 长 Linq 操作?

c - 删除 1 GB 内存需要多长时间?

c# - LINQ 按名称选择属性

c# - 转换器不转换文化数字格式?

c# - 如何使用 .NET 更改本地安全策略

c# - 两个列表的 linq 并集

c# - 声明一个空的 Queryable?