Несколько расширений файла searchPattern для System.IO.Directory.GetFiles - PullRequest
122 голосов
/ 12 августа 2011

Каков синтаксис для установки нескольких расширений файла как searchPattern на Directory.GetFiles()? Например, фильтрация файлов с расширениями .aspx и .ascx .

// TODO: Set the string 'searchPattern' to only get files with
// the extension '.aspx' and '.ascx'.
var filteredFiles = Directory.GetFiles(path, searchPattern);

Обновление : LINQ не является опцией , это должен быть searchPattern, переданный в GetFiles, как указано в вопросе.

Ответы [ 19 ]

182 голосов
/ 12 августа 2011
var filteredFiles = Directory
    .GetFiles(path, "*.*")
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

Редактировать 2014-07-23

Вы можете сделать это в .NET 4.5 для более быстрого перечисления:

var filteredFiles = Directory
    .EnumerateFiles(path) //<--- .NET 4.5
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

Directory.EnumerateFiles в MSDN

37 голосов
/ 12 августа 2011

Я считаю, что не существует готового решения, это ограничение метода Directory.GetFiles.

Довольно просто написать свой собственный метод, хотя вот пример .

Код может быть:

/// <summary>
/// Returns file names from given folder that comply to given filters
/// </summary>
/// <param name="SourceFolder">Folder with files to retrieve</param>
/// <param name="Filter">Multiple file filters separated by | character</param>
/// <param name="searchOption">File.IO.SearchOption, 
/// could be AllDirectories or TopDirectoryOnly</param>
/// <returns>Array of FileInfo objects that presents collection of file names that 
/// meet given filter</returns>
public string[] getFiles(string SourceFolder, string Filter, 
 System.IO.SearchOption searchOption)
{
 // ArrayList will hold all file names
ArrayList alFiles = new ArrayList();

 // Create an array of filter string
 string[] MultipleFilters = Filter.Split('|');

 // for each filter find mathing file names
 foreach (string FileFilter in MultipleFilters)
 {
  // add found file names to array list
  alFiles.AddRange(Directory.GetFiles(SourceFolder, FileFilter, searchOption));
 }

 // returns string array of relevant file names
 return (string[])alFiles.ToArray(typeof(string));
}
30 голосов
/ 12 августа 2011

GetFiles может соответствовать только одному шаблону, но вы можете использовать Linq для вызова GetFiles с несколькими шаблонами:

FileInfo[] fi = new string[]{"*.txt","*.doc"}
    .SelectMany(i => di.GetFiles(i, SearchOption.AllDirectories))
    .ToArray();

Смотрите раздел комментариев здесь: http://www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx

17 голосов
/ 06 мая 2015

Мне нравится этот метод, потому что он читабелен и позволяет избежать многократных итераций каталога:

var allowedExtensions = new [] {".doc", ".docx", ".pdf", ".ppt", ".pptx", ".xls", ".xslx"}; 
var files = Directory
    .GetFiles(folder)
    .Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
    .ToList();
14 голосов
/ 12 августа 2011

Боюсь, вам придется делать что-то подобное, я мутировал регулярное выражение из здесь .

var searchPattern = new Regex(
    @"$(?<=\.(aspx|ascx))", 
    RegexOptions.IgnoreCase);
var files = Directory.EnumerateFiles(path)
    .Where(f => searchPattern.IsMatch(f))
    .ToList();
14 голосов
/ 12 ноября 2013
var filteredFiles = Directory
    .EnumerateFiles(path, "*.*") // .NET4 better than `GetFiles`
    .Where(
        // ignorecase faster than tolower...
        file => file.ToLower().EndsWith("aspx")
        || file.EndsWith("ascx", StringComparison.OrdinalIgnoreCase))
    .ToList();

Или, может быть быстрее разделить и объединить ваши шары (по крайней мере, это выглядит чище):

"*.ext1;*.ext2".Split(';')
    .SelectMany(g => Directory.EnumerateFiles(path, g))
    .ToList();
4 голосов
/ 12 августа 2011

Я бы использовал следующее:

var ext = new string[] { ".ASPX", ".ASCX" };
FileInfo[] collection = (from fi in new DirectoryInfo(path).GetFiles()
                         where ext.Contains(fi.Extension.ToUpper())
                         select fi)
                         .ToArray();

РЕДАКТИРОВАТЬ: исправлено из-за несоответствия между Directory и DirectoryInfo

3 голосов
/ 28 марта 2016

Легкое для запоминания, ленивое и, возможно, несовершенное решение:

Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe"))
3 голосов
/ 09 октября 2015

Более эффективный способ получения файлов с расширениями ".aspx" и ".ascx". что позволяет избежать запросов файловой системы несколько раз и избежать возврата большого количества нежелательных файлов, заключается в предварительной фильтрации файлов с использованием приблизительного шаблона поиска и уточнения результата впоследствии:

var filteredFiles = Directory.GetFiles(path, "*.as?x")
    .Select(f => f.ToLowerInvariant())
    .Where(f => f.EndsWith("px") || f.EndsWith("cx"))
    .ToList();
2 голосов
/ 12 октября 2015

Вместо функции EndsWith я бы выбрал вместо этого метод Path.GetExtension().Вот полный пример:

var filteredFiles = Directory.EnumerateFiles( path )
.Where(
    file => Path.GetExtension(file).Equals( ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            Path.GetExtension(file).Equals( ".ascx", StringComparison.OrdinalIgnoreCase ) );

или:

var filteredFiles = Directory.EnumerateFiles(path)
.Where(
    file => string.Equals( Path.GetExtension(file), ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            string.Equals( Path.GetExtension(file), ".ascx", StringComparison.OrdinalIgnoreCase ) );

(используйте StringComparison.OrdinalIgnoreCase, если вам нужна производительность: Сравнение строк MSDN )

...