Directory.EnumerateFiles не возвращает файлы в случае нескольких расширений

У меня есть проблема, с которой я не могу справиться.

Когда я использую EnumerateFiles, он не возвращает файлы, хотя я знаю, что должно быть более 3 тыс. результатов.

Мой код выглядит так:

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

Ни одно из решений не работает, и мне нужно это решение для нескольких расширений. Единственный метод, который работал для меня, это:

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

Который работает, но только для одного расширения.

Пожалуйста, помогите мне, ребята, я не хочу использовать GetFiles, который очень медленный (у меня более 10 тысяч файлов в папке).

EDIT1 Я вызываю метод с этим фильтром:

string[] extensions = {"png"};

ИЗМЕНИТЬ2

Мой пример для воспроизведения:

    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));
}

person user1750355    schedule 30.10.2015    source источник
comment
Возможно, exts уже содержит .. Вы должны показать пример. Сколько расширений вы фильтруете?   -  person Tim Schmelter    schedule 30.10.2015
comment
На самом деле не существует такой вещи, как несколько расширений, но я думаю, вы имеете в виду файлы с точкой в ​​имени файла (без расширения), например foo.bar.txt? Или вы хотите перечислить все *.txt и все *.jpg файлы? Можете ли вы показать несколько примеров имен файлов и пример ввода для этого метода?   -  person CodeCaster    schedule 30.10.2015
comment
Могу ли я предложить для начала иметь менее 10 000 файлов в папке?   -  person MicroVirus    schedule 30.10.2015
comment
Если вы просто хотите, например. *.jpg и *.gif, то если вторая версия работает для одного конкретного расширения, а первая версия показывает, как объединить результаты нескольких вызовов Directory.EnumerateFiles, что произойдет, если вы объедините их?   -  person    schedule 30.10.2015
comment
Спасибо за ответы. Я вызываю метод следующим образом: string[] extensions = {png}; так что нет точек в расширении   -  person user1750355    schedule 30.10.2015
comment
Этот код работает для меня. Это ваш реальный код или вы на самом деле вызываете return extsAsWildcards.Select(...), дважды добавляя *.? Создайте минимально воспроизводимый пример.   -  person CodeCaster    schedule 30.10.2015
comment
Это мой реальный код.   -  person user1750355    schedule 30.10.2015


Ответы (1)


Ваш подход медленный, потому что вы ищете эту папку, содержащую 10 000 файлов, несколько раз (для каждого расширения). Вместо этого вы можете использовать это:

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 прокомментировал это было чувствительно к регистру. Теперь он нечувствителен к регистру. Так что не имеет значения, является ли расширение png или PNG. Возможно, это было причиной вашей проблемы.

person Tim Schmelter    schedule 30.10.2015
comment
При вызове возвращает: Empty = Перечисление не дало результатов Проблема не в медленности. Проблема в том, что он ничего не возвращает - person user1750355; 30.10.2015
comment
Проблема OP в том, что этот код не работает, а GetFiles [..] работает очень медленно. Это не настоящий код OP. - person CodeCaster; 30.10.2015
comment
если файлы находятся в другом каталоге, добавьте SearchOption.AllDirectories, как тот, который работал у вас, может быть, проблема в этом? @user1750355 - person M.kazem Akhgary; 30.10.2015
comment
@CodeCaster: Если GetFiles очень медленный, то и EnumerableFiles очень медленный, потому что им обоим нужно несколько раз искать в этой огромной папке, чтобы найти файлы с нужными расширениями. Другая возможная причина, по которой код OP может дать сбой, заключается в том, что он передает расширения, которые уже содержат . (например, возвращаемые IO.Path.GetExtension). Это исправлено с помощью StartsWith. Если он по-прежнему не работает (что, кажется, так и есть), трудно помочь, потому что он должен работать. - person Tim Schmelter; 30.10.2015
comment
Мои расширения не содержат точек. Пожалуйста, посмотрите на EDIT1 - person user1750355; 30.10.2015
comment
@user, пожалуйста, создайте пример, который воспроизводит проблему. - person CodeCaster; 30.10.2015
comment
Разве это не должно быть .Select(x => x.StartsWith(".") ? x : "." + x)? Кроме того, возникают проблемы при смешивании верхнего и нижнего регистра. - person MicroVirus; 30.10.2015
comment
Я добавил Edit2 с моим примером - person user1750355; 30.10.2015
comment
@MicroVirus: вы правы, это проблема с копированием и вставкой. Фиксированный - person Tim Schmelter; 30.10.2015
comment
Я имею в виду сопоставление pic001.JPEG из EnumerateFiles с расширением jpeg в exts. - person MicroVirus; 30.10.2015
comment
@MicroVirus: да, хороший улов. Фиксированный - person Tim Schmelter; 30.10.2015