【问题标题】:Directory.EnumerateFiles returns no files in case of multiple extensionsDirectory.EnumerateFiles 在多个扩展名的情况下不返回文件
【发布时间】:2016-01-31 01:38:48
【问题描述】:

我有一个我无法处理的问题。

当我使用 EnumerateFiles 时,它不返回任何文件,我知道应该有超过 3k 个结果。

我的代码如下所示:

private IEnumerable<string> TestGetFiles(string path, params string[] exts)
    {
        var extsAsWildcards = exts.Select(x => "*." + x).ToArray();
        return exts.Select(x => "*." + x) .SelectMany(x => Directory.EnumerateFiles(path, x));

    }

我从这里获取了这个代码:Git link

没有一个解决方案有效,我需要这个解决方案来进行多个扩展。唯一对我有用的方法是:

private IEnumerable<string> GetCurrentFontFiles(string item)
    {
        IEnumerable<string> files = Directory.EnumerateFiles(item + Path.DirectorySeparatorChar, "*.ttf", SearchOption.AllDirectories).ToArray();
        return files;
    }

这有效,但仅适用于单个扩展。

请帮帮我,我不想使用速度极慢的 GetFiles(我的文件夹中有超过 10k 个文件)。

EDIT1 我用这个过滤器调用方法:

string[] extensions = {"png"};

EDIT2

我要重现的例子:

    private IEnumerable<string> TestGetFiles(string path, params string[] exts)
    {
        return exts.Select(x => "*." + x).SelectMany(x => Directory.EnumerateFiles(path, x));
    }
    private List<FileSizeList> GetPNGFiles(string pathForFiles)
    {
        List<FileSizeList> PNGFiles = new List<FileSizeList>();

        string[] extensions = {"png"};
        IEnumerable<string> files = TestGetFiles(pathForFiles, extensions);
        foreach (var file in files)
        { //no iteration here

        }
    }

EDIT3 工作解决方案

我知道问题出在哪里。我修改了一个代码并添加了缺少的 SearchOption

private IEnumerable<string> TestGetFiles(string path, params string[] exts)
{
    var extensions = exts
       .Select(x => x.StartsWith(".") ? x : "." + x)
       .ToArray();
    return Directory.EnumerateFiles(path,"*.*",SearchOption.AllDirectories)
        .Where(fn => extensions.Contains(Path.GetExtension(fn), StringComparer.InvariantCultureIgnoreCase));
}

【问题讨论】:

  • 可能exts 已经包含.。你应该展示一个例子。你过滤了多少个扩展?
  • 实际上并没有“多个扩展名”这样的东西,但我认为您的意思是文件名中带有点的文件(没有扩展名),例如foo.bar.txt?还是您的意思是要枚举所有 *.txt 和所有 *.jpg 文件?您能否展示一些示例文件名和此方法的示例输入?
  • 我可以建议一个文件夹中的文件数量少于 10k 吗?
  • 如果你的意思是你想要例如*.jpg 和 *.gif,那么如果第二个版本适用于一个特定的扩展,而第一个版本显示如何组合多次调用 Directory.EnumerateFiles 的结果,如果将两者结合起来会发生什么?
  • 这段代码对我有用。这是您的实际代码,还是您实际上调用return extsAsWildcards.Select(...),添加*. 两次?请创建一个minimal reproducible example

标签: c# file-io system.io.directory


【解决方案1】:

您的方法很慢,因为您要多次搜索这个包含 10k 个文件的文件夹(对于每个扩展名)。相反,您可以使用它:

private IEnumerable<string> TestGetFiles(string path, params string[] exts)
{
    var extensions  = exts
       .Select(x => x.StartsWith(".") ? x : "." + x)
       .ToArray();
    return Directory.EnumerateFiles(path ,SearchOption.AllDirectories)            
       . Where(fn => extensions.Contains(Path.GetExtension(fn), StringComparer.InvariantCultureIgnoreCase));
}

显然您还想搜索子目录。然后使用AllDirectories

由于 MicroVirus 有 commented,它区分大小写。现在它不区分大小写。所以扩展名是png还是PNG都没有关系。也许这导致了您的问题。

【讨论】:

  • 调用它时返回: Empty = "Enumeration yielded no results" 问题不是它很慢。问题是它没有返回任何东西
  • OP 的问题是“此代码不起作用”和“GetFiles [..] 非常慢”。这不是 OP 的实际代码。
  • 如果文件在另一个目录中,请添加SearchOption.AllDirectories 喜欢为您工作的那个可能就是问题所在? @user1750355
  • @CodeCaster:如果GetFiles 非常慢,EnumerableFiles 也非常慢,因为他们都需要多次搜索这个巨大的文件夹才能找到具有所需扩展名的文件。 OP 的代码可能失败的另一个可能原因是,如果他传递了已经包含 . 的扩展名(例如由 IO.Path.GetExtension 返回)。这是用StartsWith 修复的。如果它仍然不起作用(似乎是这种情况),则很难提供帮助,因为它应该起作用。
  • 我的意思是将EnumerateFiles中的“pic001.JPEG”与exts中的“jpeg”扩展名匹配。
猜你喜欢
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
相关资源
最近更新 更多