首页 > 解决方案 > 使用 EnumerateFiles 和多个过滤器(文件扩展名)读取文件

问题描述

我需要从文件夹和子文件夹中动态加载文件。

我使用此代码加载我的文件:

    var files = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
        .Where(s => s.EndsWith(".txt") || s.EndsWith(".xml") || s.EndsWith(".log") || s.EndsWith(".csv"))
        .ToList();

它很慢,但比我已经尝试过的所有其他方法都要好。

现在我想改变这条线以使其具有动态性,以便我可以过滤我的扩展

.Where(s => s.EndsWith(".txt") || s.EndsWith(".xml") || s.EndsWith(".log") || s.EndsWith(".csv"))

所以,第一步我用这个替换我的行:

filter.Split('|').ToList().ForEach(y =>
{
    files.AddRange(Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
        .Where(s => s.EndsWith(y))
        .ToList());
});

但是我也可以删除 Where 指令并使用 EnumerateFiles() 中的过滤器。是的,确定。但问题也在于这样做我对 EnumerateFiles() 进行了多次调用,这甚至更慢。

我能做些什么?

这是否更好

var allFiles = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories);
var files = new List<string>();

filter.Split('|').ToList().ForEach(y =>
{
    files.AddRange(allFiles.Where(s => s.EndsWith(y)).ToList());
});

标签: c#filesystems

解决方案


我会做以下事情

var extensions = filter.Split('|').ToHashSet(StringComparer.OrdinalIgnoreCase);
var files = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
    .Where(s => extensions.Contains(Path.GetExtension(s)))
    .ToList();

编辑:

仅供参考,您的Is this better代码与您之前的代码 100% 相同。 IEnumerable是惰性的,只会在使用时执行,所以 var allFiles = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories);在循环之外声明没有区别。

在这里看到一个演示: https ://dotnetfiddle.net/UZj8lr


推荐阅读