¿Cómo hacer una lista recursiva de todos los archivos en un directorio en C #?

¿Cómo hacer una recursiva lista de todos los archivos en un directorio y directorios secundarios en C #?

Este artículo cubre todo lo que necesita. Excepto en lugar de buscar los archivos y comparar nombres, simplemente imprima los nombres.

Se puede modificar así:

static void DirSearch(string sDir) { try { foreach (string d in Directory.GetDirectories(sDir)) { foreach (string f in Directory.GetFiles(d)) { Console.WriteLine(f); } DirSearch(d); } } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } } 

Tenga en cuenta que en .NET 4.0 hay (supuestamente) funciones de archivos basadas en iteradores (en lugar de basadas en matrices) integradas:

 foreach (string file in Directory.EnumerateFiles( path, "*.*", SearchOption.AllDirectories)) { Console.WriteLine(file); } 

Por el momento usaría algo como abajo; el método recursivo incorporado se rompe demasiado fácilmente si no tiene acceso a un solo subdirectorio …; el uso de Queue evita demasiada recursión de la stack de llamadas, y el bloque iterator nos evita tener una gran matriz.

 static void Main() { foreach (string file in GetFiles(SOME_PATH)) { Console.WriteLine(file); } } static IEnumerable GetFiles(string path) { Queue queue = new Queue(); queue.Enqueue(path); while (queue.Count > 0) { path = queue.Dequeue(); try { foreach (string subDir in Directory.GetDirectories(path)) { queue.Enqueue(subDir); } } catch(Exception ex) { Console.Error.WriteLine(ex); } string[] files = null; try { files = Directory.GetFiles(path); } catch (Exception ex) { Console.Error.WriteLine(ex); } if (files != null) { for(int i = 0 ; i < files.Length ; i++) { yield return files[i]; } } } } 
 Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories) 

En .NET 4.5, al menos, existe esta versión que es mucho más corta y tiene la ventaja adicional de evaluar cualquier criterio de archivo para su inclusión en la lista:

  ///  public static IEnumerable GetAllFiles(string path, Func checkFile = null) { string mask = Path.GetFileName(path); if (string.IsNullOrEmpty(mask)) mask = "*.*"; path = Path.GetDirectoryName(path); string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories); foreach (string file in files) { if (checkFile == null || checkFile(new FileInfo(file))) yield return file; } } 

Use como:

  string folder = Config.TestInput(); string mask = folder + "*.*"; var list = UT.GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList(); Assert.AreNotEqual(0, list.Count); var lastQuarter = DateTime.Now.AddMonths(-3); list = UT.GetAllFiles(mask, (info) => info.CreationTime >= lastQuarter).ToList(); Assert.AreNotEqual(0, list.Count); 
 IEnumerable GetFilesFromDir(string dir) => Directory.EnumerateFiles(dir).Concat( Directory.EnumerateDirectories(dir) .SelectMany(subdir => GetFilesFromDir(subdir))); 

En Framework 2.0 puede usar (lista los archivos de la carpeta raíz, es la mejor respuesta).

 static void DirSearch(string dir) { try { foreach (string f in Directory.GetFiles(dir)) Console.WriteLine(f); foreach (string d in Directory.GetDirectories(dir)) { Console.WriteLine(d); DirSearch(d); } } catch (System.Exception ex) { Console.WriteLine(ex.Message); } } 

Algunas respuestas excelentes, pero estas respuestas no resolvieron mi problema.

Tan pronto como surge un problema de permiso de carpeta: “Permiso denegado”, el código falla. Esto es lo que solía hacer con el tema “Permiso denegado”:

 private int counter = 0; private string[] MyDirectories = Directory.GetDirectories("C:\\"); private void ScanButton_Click(object sender, EventArgs e) { Thread MonitorSpeech = new Thread(() => ScanFiles()); MonitorSpeech.Start(); } private void ScanFiles() { string CurrentDirectory = string.Empty; while (counter < MyDirectories.Length) { try { GetDirectories(); CurrentDirectory = MyDirectories[counter++]; } catch { if (!this.IsDisposed) { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + CurrentDirectory); }); } } } } private void GetDirectories() { foreach (string directory in MyDirectories) { GetFiles(directory); } } private void GetFiles(string directory) { try { foreach (string file in Directory.GetFiles(directory, "*")) { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add(file); }); } } catch { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + directory); }); } } 

Espero que esto ayude a otros.

Una solución simple y limpia

 ///  /// Scans a folder and all of its subfolders recursively, and updates the List of files ///  /// Full path of the folder /// The list, where the output is expected internal static void EnumerateFiles(string sFullPath, List fileInfoList) { try { DirectoryInfo di = new DirectoryInfo(sFullPath); FileInfo[] files = di.GetFiles(); foreach (FileInfo file in files) fileInfoList.Add(file); //Scan recursively DirectoryInfo[] dirs = di.GetDirectories(); if (dirs == null || dirs.Length < 1) return; foreach (DirectoryInfo dir in dirs) EnumerateFiles(dir.FullName, fileInfoList); } catch (Exception ex) { Logger.Write("Exception in Helper.EnumerateFiles", ex); } } 

}

Prefiero usar DirectoryInfo porque puedo obtener FileInfo, no solo cadenas.

  string baseFolder = @"C:\temp"; DirectoryInfo di = new DirectoryInfo(baseFolder); string searchPattern = "*.xml"; ICollection matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories) .Select(x => x) .ToList(); 

Lo hago en caso de que en el futuro necesite un futuro filtrado … en función de las propiedades de FileInfo.

  string baseFolder = @"C:\temp"; DirectoryInfo di = new DirectoryInfo(baseFolder); string searchPattern = "*.xml"; ICollection matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories) .Where(x => x.LastWriteTimeUtc < DateTimeOffset.Now) .Select(x => x) .ToList(); 

También puedo recurrir a cadenas si es necesario. (y todavía estoy a prueba de futuro para cosas de filtros / donde-cláusula.

  string baseFolder = @"C:\temp"; DirectoryInfo di = new DirectoryInfo(baseFolder); string searchPattern = "*.xml"; ICollection matchingFileNames = di.GetFiles(searchPattern, SearchOption.AllDirectories) .Select(x => x.FullName) .ToList(); 

Tenga en cuenta que ” . ” Es un patrón de búsqueda válido si desea declarar por extensión.

Este es mi punto de vista, basado en Hernaldo, si necesitas encontrar archivos con nombres de cierto patrón, como archivos XML que en algún lugar de su nombre contengan una cadena en particular:

 // call this like so: GetXMLFiles("Platypus", "C:\\"); public static List GetXMLFiles(string fileType, string dir) { string dirName = dir; var fileNames = new List(); try { foreach (string f in Directory.GetFiles(dirName)) { if ((f.Contains(fileType)) && (f.Contains(".XML"))) { fileNames.Add(f); } } foreach (string d in Directory.GetDirectories(dirName)) { GetXMLFiles(fileType, d); } } catch (Exception ex) { MessageBox.Show(ex.Message); } return fileNames; } 

Listado de archivos y carpetas para modelar, implementación personalizada.
Esto crea una lista completa de todos los archivos y carpetas comenzando desde su directorio de inicio.

 public class DirOrFileModel { #region Private Members private string _name; private string _location; private EntryType _entryType; #endregion #region Bindings public string Name { get { return _name; } set { if (value == _name) return; _name = value; } } public string Location { get { return _location; } set { if (value == _location) return; _location = value; } } public EntryType EntryType { get { return _entryType; } set { if (value == _entryType) return; _entryType = value; } } public ObservableCollection Entries { get; set; } #endregion #region Constructor public DirOrFileModel() { Entries = new ObservableCollection(); } #endregion } public enum EntryType { Directory = 0, File = 1 } 

Método:

  static DirOrFileModel DirSearch(DirOrFileModel startDir) { var currentDir = startDir; try { foreach (string d in Directory.GetDirectories(currentDir.Location)) { var newDir = new DirOrFileModel { EntryType = EntryType.Directory, Location = d, Name = Path.GetFileName(d) }; currentDir.Entries.Add(newDir); DirSearch(newDir); } foreach (string f in Directory.GetFiles(currentDir.Location)) { var newFile = new DirOrFileModel { EntryType = EntryType.File, Location = f, Name = Path.GetFileNameWithoutExtension(f) }; currentDir.Entries.Add(newFile); } } catch (Exception excpt) { Console.WriteLine(excpt.Message); } return startDir; } 

Uso:

 var dir = new DirOrFileModel { Name = "C", Location = @"C:\", EntryType = EntryType.Directory }; dir = DirSearch(dir); 
 static void Main(string[] args) { string[] array1 = Directory.GetFiles(@"D:\"); string[] array2 = System.IO.Directory.GetDirectories(@"D:\"); Console.WriteLine("--- Files: ---"); foreach (string name in array1) { Console.WriteLine(name); } foreach (string name in array2) { Console.WriteLine(name); } Console.ReadLine(); } 
 private void GetFiles(DirectoryInfo dir, ref List files) { try { files.AddRange(dir.GetFiles()); DirectoryInfo[] dirs = dir.GetDirectories(); foreach (var d in dirs) { GetFiles(d, ref files); } } catch (Exception e) { } } 

Solución corta y simple

 string dir = @"D:\PATH"; DateTime from_date = DateTime.Now.Date; DateTime to_date = DateTime.Now.Date.AddHours(23); var files = Directory.EnumerateFiles(dir, "*.*",SearchOption.AllDirectories).Select(i=>new FileInfo(i)) .Where(file=>file.LastWriteTime >= from_date && file.LastWriteTime <= to_date); foreach(var fl in files) Console.WriteLine(fl.FullName); 

Este me ayudó a obtener todos los archivos en un directorio y subdirectorios, puede ser útil para alguien. [Inspirado de las respuestas anteriores]

 static void Main(string[] args) { try { var root = @"G:\logs"; DirectorySearch(root); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); } public static void DirectorySearch(string root, bool isRootItrated = false) { if (!isRootItrated) { var rootDirectoryFiles = Directory.GetFiles(root); foreach (var file in rootDirectoryFiles) { Console.WriteLine(file); } } var subDirectories = Directory.GetDirectories(root); if (subDirectories?.Any() == true) { foreach (var directory in subDirectories) { var files = Directory.GetFiles(directory); foreach (var file in files) { Console.WriteLine(file); } DirectorySearch(directory, true); } } } 

Aquí hay una versión del código de B. Clay Shannon no estática para los archivos de Excel:

 class ExcelSearcher { private List _fileNames; public ExcelSearcher(List filenames) { _fileNames = filenames; } public List GetExcelFiles(string dir, List filenames = null) { string dirName = dir; var dirNames = new List(); if (filenames != null) { _fileNames.Concat(filenames); } try { foreach (string f in Directory.GetFiles(dirName)) { if (f.ToLower().EndsWith(".xls") || f.ToLower().EndsWith(".xlsx")) { _fileNames.Add(f); } } dirNames = Directory.GetDirectories(dirName).ToList(); foreach (string d in dirNames) { GetExcelFiles(d, _fileNames); } } catch (Exception ex) { //Bam } return _fileNames; }