System.IO.Directory.GetFiles的多个文件扩展名searchPattern

Seb*_*son 125 .net c# system.io.directory

什么是设置语法多个文件的扩展searchPatternDirectory.GetFiles()?例如,使用.aspx.ascx扩展名过滤掉文件.

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

更新:LINQ不是一个选项,它必须是一个searchPattern传入GetFiles,如问题中所指定的.

jga*_*fin 184

var filteredFiles = Directory
    .GetFiles(path, "*.*")
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

编辑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();
Run Code Online (Sandbox Code Playgroud)

MSDN中的Directory.EnumerateFiles

  • 你可以随时使用`file.EndsWith("...",StringComparison.InvariantCultureIgnoreCase);`而不是`ToLower` (6认同)
  • @Mario Vernari:`GetFiles`返回`string []`. (5认同)
  • 您必须从EndsWith()参数中删除*,它不会执行通配符匹配. (4认同)
  • 如果比较文件的扩展名,它将返回完全匹配,如'.Where(file => new FileInfo(file).Extension.Equals(".aspx")|| new FileInfo(file).Extension.Equals(".ascx") )" (3认同)
  • 不要忘记新的.NET4`Directory.EnumerateFiles`以提高性能...... http://stackoverflow.com/questions/5669617/what-is-the-difference-between-directory-enumeratefiles-vs-directory-的GetFiles (3认同)
  • Path.GetExtension()更适合于获取文件扩展名,至少您应该在扩展名“ .aspx”之前添加点 (3认同)
  • +1用于将问题分解为多个部分. (2认同)
  • @Damith确实,但我认为它会更重 (2认同)

Dan*_*l B 38

我相信没有"开箱即用"的解决方案,这是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));
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一种非常不充分的方法,因为您将为每个过滤器循环整个目录.相反,如果每个文件都有过滤器,则应检查每个文件,然后添加以执行列表.您可以使用此主题中解释的答案:http://stackoverflow.com/questions/3754118/how-to-filter-directory-enumeratefiles-with-multiple-criteria (7认同)

小智 30

GetFiles只能匹配单个模式,但您可以使用Linq调用具有多个模式的GetFiles:

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

请参阅以下评论部分:http: //www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx

  • 为什么`Distinct`?他们不应该碰撞,对吧? (6认同)
  • 如果模式重叠,它们将发生冲突。例如,`new string [] {“ *。txt”,“ filename。*”}`。但是,对Distinct的调用实际上无法解决此问题,因为FileInfo对象使用引用相等而不是语义相等进行比较。可以通过删除Distinct或将其传递给IEqualityComparer &lt;FileInfo&gt;来解决。编辑做前者。 (2认同)

Mar*_*arc 18

我喜欢这种方法,因为它是可读的并且避免了目录的多次迭代:

var allowedExtensions = new [] {".doc", ".docx", ".pdf", ".ppt", ".pptx", ".xls", ".xslx"}; 
var files = Directory
    .GetFiles(folder)
    .Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢这个,因为我不必解析我的扩展数组并将其添加到正则表达式或其他手动工作中。谢谢! (2认同)

Jod*_*ell 15

我担心你必须做这样的事情,我从这里改变了正则表达式.

var searchPattern = new Regex(
    @"$(?<=\.(aspx|ascx))", 
    RegexOptions.IgnoreCase);
var files = Directory.EnumerateFiles(path)
    .Where(f => searchPattern.IsMatch(f))
    .ToList();
Run Code Online (Sandbox Code Playgroud)


drz*_*aus 14

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();
Run Code Online (Sandbox Code Playgroud)

或者,拆分和合并你的globs可能会更快(至少它看起来更干净):

"*.ext1;*.ext2".Split(';')
    .SelectMany(g => Directory.EnumerateFiles(path, g))
    .ToList();
Run Code Online (Sandbox Code Playgroud)


jon*_*han 8

易于记忆、懒惰且可能不完美的解决方案:

Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe"))
Run Code Online (Sandbox Code Playgroud)