c# .net system.io.directory

c# - Multiple file-extensions searchPattern para System.IO.Directory.GetFiles



.net (18)

¿Cuál es la sintaxis para configurar múltiples extensiones de archivo como searchPattern en Directory.GetFiles() ? Por ejemplo, filtrando archivos con extensiones .aspx y .ascx .

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

Actualización : LINQ no es una opción , tiene que ser un searchPattern pasado a GetFiles , como se especifica en la pregunta.


@ Daniel B, gracias por la sugerencia de escribir mi propia versión de esta función. Tiene el mismo comportamiento que Directory.GetFiles, pero admite el filtrado de expresiones regulares.

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

Lo encontré útil, así que pensé que lo compartiría.


Creo que no hay una solución "lista para usar", eso es una limitación del método Directory.GetFiles.

Sin embargo, es bastante fácil escribir su propio método, aquí hay un example .

El código podría ser:

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


En lugar de la función EndsWith, elegiría utilizar el método Path.GetExtension() lugar. Aquí está el ejemplo completo:

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

o:

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

(Utilice StringComparison.OrdinalIgnoreCase si le importa el rendimiento: comparaciones de cadenas de MSDN )


GetFiles solo puede coincidir con un patrón único, pero puede usar Linq para invocar GetFiles con múltiples patrones:

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

Vea la sección de comentarios aquí: http://www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx


Intentaré especificar algo como

var searchPattern = "as?x";

deberia de funcionar.


La solución fácil de recordar, floja y tal vez imperfecta:

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


Me gusta este método, porque es legible y evita múltiples iteraciones del directorio:

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


Me temo que tendrás que hacer algo como esto, he mutado la expresión regular desde here .

var searchPattern = new Regex( @"$(?<=/.(aspx|ascx))", RegexOptions.IgnoreCase); var files = Directory.GetFiles(path).Where(f => searchPattern.IsMatch(f));


Solo quisiera decir que si usa FileIO.FileSystem.GetFiles lugar de Directory.GetFiles , permitirá una matriz de comodines.

Por ejemplo:

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


Una forma más eficiente de obtener archivos con las extensiones ".aspx" y ".ascx" que evita consultar el sistema de archivos varias veces y evita devolver muchos archivos no deseados, es prefiltrar los archivos utilizando un patrón de búsqueda aproximado y para refinar el resultado después:

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


Versión c # de la respuesta de @ qfactor77. Esta es la mejor manera sin LINQ.

string[] wildcards= {"*.mp4", "*.jpg"}; ReadOnlyCollection<string> filePathCollection = FileSystem.GetFiles(dirPath, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, wildcards); string[] filePath=new string[filePathCollection.Count]; filePathCollection.CopyTo(filePath,0);

ahora devuelve la matriz de cadena de filePath . Al principio necesitas

using Microsoft.VisualBasic.FileIO; using System.Collections.ObjectModel;

también necesita agregar referencia a Microsoft.VisualBasic


Yo usaría lo siguiente:

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

EDITAR: corregido desajuste entre Directorio y DirectoryInfo


mira como esta demostración:

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


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


var filtered = Directory.GetFiles(path) .Where(file => file.EndsWith("aspx", StringComparison.InvariantCultureIgnoreCase) || file.EndsWith("ascx", StringComparison.InvariantCultureIgnoreCase)) .ToList();


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

O bien, puede ser más rápido dividir y unir tus globs (al menos se ve más limpio):

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


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

Editar 2014-07-23

Puede hacer esto en .NET 4.5 para una enumeración más rápida:

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

Directory.EnumerateFiles en MSDN