Come elencare in modo ricorsivo tutti i file in una directory in C #?

Come elencare in modo ricorsivo tutti i file in una directory e le directory secondarie in C #?

Questo articolo copre tutto ciò di cui hai bisogno. Tranne che per cercare i file e confrontare i nomi, basta stampare i nomi.

Può essere modificato in questo modo:

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

Si noti che in .NET 4.0 sono presenti (presumibilmente) funzioni di file basate su iteratore (piuttosto che basate su array) incorporate:

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

Al momento userò qualcosa come sotto; il metodo ricorsivo integrato si interrompe troppo facilmente se non si ha accesso a una singola sotto-dir …; l’uso di Queue evita troppe ricorsioni di call-stack e il blocco iteratore ci evita di avere un enorme array.

 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) 

In .NET 4.5, almeno, c’è questa versione che è molto più breve e ha il vantaggio di valutare qualsiasi criterio di file per l’inclusione nell’elenco:

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

Usa come:

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

In Framework 2.0 puoi usare (elenca i file della cartella principale, è la migliore risposta più popolare):

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

Alcune risposte eccellenti ma queste risposte non hanno risolto il mio problema.

Non appena si verifica un problema di authorization alla cartella: “Autorizzazione negata” il codice non riesce. Questo è quello che ho usato per aggirare il problema “Permesso negato”:

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

Spero che questo aiuti gli altri.

Una soluzione semplice e pulita

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

}

Preferisco usare DirectoryInfo perché posso ottenere FileInfo, non solo stringhe.

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

Lo faccio nel caso in cui in futuro avrò bisogno del futuro filtro … basato sulle proprietà di 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(); 

Posso anche ricorrere a stringhe se necessario. (e sono ancora a prova di futuro per i filtri / roba where-clause.

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

Nota che ” . ” È un modello di ricerca valido se vuoi filer per estensione.

Ecco il mio punto di vista, basato su Hernaldo’s, se hai bisogno di trovare i file con i nomi di un determinato pattern, come i file XML che da qualche parte nel loro nome contengono una stringa particolare:

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

Elenco di file e cartelle da modellare, implementazione personalizzata.
Questo crea un elenco completo di tutti i file e le cartelle a partire dalla directory di avvio.

 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 } 

Metodo:

  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) { } } 

Soluzione breve e semplice

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

Questo mi ha aiutato a ottenere tutti i file in una directory e sottodirectory, può essere utile per qualcuno. [Ispirato dalle risposte di sopra]

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

Ecco una versione del codice di B. Clay Shannon non statico per i file 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; }