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

Directory.GetFiles()上设置多个文件扩展名为searchPattern的语法是什么? 例如,用.aspx.ascx扩展名筛选文件。

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

更新LINQ不是一个选项 ,它必须是一个传入GetFilessearchPattern ,如问题中指定的那样。

我相信没有“开箱即用”的解决scheme,这是Directory.GetFiles方法的限制。

尽pipe如此,编写自己的方法还是相当容易的,下面是一个例子 。

代码可以是:

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

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

我担心你必须做这样的事情,我从这里突变了正则expression式。

 var searchPattern = new Regex( @"$(?<=\.(aspx|ascx))", RegexOptions.IgnoreCase); var files = Directory.GetFiles(path).Where(f => searchPattern.IsMatch(f)); 
 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(); 
  • 不要忘了新的.NET4 Directory.EnumerateFiles性能提升( Directory.EnumerateFiles与Directory.GetFiles有什么区别? )
  • “IgnoreCase”应该比“ToLower”

或者,分割和合并你的球体可能会更快(至less看起来更干净):

 "*.ext1;*.ext2".Split(';') .SelectMany(g => Directory.EnumerateFiles(path, g)) .ToList(); 

我喜欢这个方法,因为它是可读的,避免了多次迭代:

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

我会使用以下内容:

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

编辑:更正由于目录和DirectoryInfo之间的不匹配

我会尝试指定类似的东西

 var searchPattern = "as?x"; 

它应该工作。

  /// <summary> /// Returns the names of files in a specified directories that match the specified patterns using LINQ /// </summary> /// <param name="srcDirs">The directories to seach</param> /// <param name="searchPatterns">the list of search patterns</param> /// <param name="searchOption"></param> /// <returns>The list of files that match the specified pattern</returns> public static string[] GetFilesUsingLINQ(string[] srcDirs, string[] searchPatterns, SearchOption searchOption = SearchOption.AllDirectories) { var r = from dir in srcDirs from searchPattern in searchPatterns from f in Directory.GetFiles(dir, searchPattern, searchOption) select f; return r.ToArray(); } 
  public static bool CheckFiles(string pathA, string pathB) { string[] extantionFormat = new string[] { ".war", ".pkg" }; return CheckFiles(pathA, pathB, extantionFormat); } public static bool CheckFiles(string pathA, string pathB, string[] extantionFormat) { System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA); System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB); // Take a snapshot of the file system. list1/2 will contain only WAR or PKG // files // fileInfosA will contain all of files under path directories FileInfo[] fileInfosA = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories); // list will contain all of files that have ..extantion[] // Run on all extantion in extantion array and compare them by lower case to // the file item extantion ... List<System.IO.FileInfo> list1 = (from extItem in extantionFormat from fileItem in fileInfosA where extItem.ToLower().Equals (fileItem.Extension.ToLower()) select fileItem).ToList(); // Take a snapshot of the file system. list1/2 will contain only WAR or // PKG files // fileInfosA will contain all of files under path directories FileInfo[] fileInfosB = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories); // list will contain all of files that have ..extantion[] // Run on all extantion in extantion array and compare them by lower case to // the file item extantion ... List<System.IO.FileInfo> list2 = (from extItem in extantionFormat from fileItem in fileInfosB where extItem.ToLower().Equals (fileItem.Extension.ToLower()) select fileItem).ToList(); FileCompare myFileCompare = new FileCompare(); // This query determines whether the two folders contain // identical file lists, based on the custom file comparer // that is defined in the FileCompare class. return list1.SequenceEqual(list2, myFileCompare); } 

使用扩展名“.aspx”和“.ascx”避免多次查询文件系统并避免返回大量不需要的文件的扩展名为“.aspx”和“.ascx”的更有效的方法是使用近似的search模式对文件进行预过滤,之后改进结果:

 var filteredFiles = Directory.GetFiles(path, "*.as?x") .Select(f => f.ToLowerInvariant()) .Where(f => f.EndsWith("px") || f.EndsWith("cx")) .ToList(); 

而不是EndsWith函数,我会select使用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 : MSDNstring比较 )

易于记忆,懒惰,也许不完美的解决scheme:

 Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe")) 

看起来像这个演示:

 void Main() { foreach(var f in GetFilesToProcess("c:\\", new[] {".xml", ".txt"})) Debug.WriteLine(f); } private static IEnumerable<string> GetFilesToProcess(string path, IEnumerable<string> extensions) { return Directory.GetFiles(path, "*.*") .Where(f => extensions.Contains(Path.GetExtension(f).ToLower())); } 
 var filtered = Directory.GetFiles(path) .Where(file => file.EndsWith("aspx", StringComparison.InvariantCultureIgnoreCase) || file.EndsWith("ascx", StringComparison.InvariantCultureIgnoreCase)) .ToList(); 

@丹尼尔B,感谢您的build议,写我自己的版本的这个function。 它具有与Directory.GetFiles相同的行为,但支持正则expression式过滤。

 string[] FindFiles(FolderBrowserDialog dialog, string pattern) { Regex regex = new Regex(pattern); List<string> files = new List<string>(); var files=Directory.GetFiles(dialog.SelectedPath); for(int i = 0; i < files.Count(); i++) { bool found = regex.IsMatch(files[i]); if(found) { files.Add(files[i]); } } return files.ToArray(); } 

我发现它很有用,所以我想我会分享。

只是想说,如果使用FileIO.FileSystem.GetFiles而不是Directory.GetFiles ,它将允许一个通配符数组。

例如:

 Dim wildcards As String() = {"*.html", "*.zip"} Dim ListFiles As List(Of String) = FileIO.FileSystem.GetFiles(directoryyouneed, FileIO.SearchOption.SearchTopLevelOnly, wildcards).ToList