Recherche de fichier dans des répertoires récursifs

J’ai le code suivant pour rechercher de manière récursive des fichiers via un répertoire, qui renvoie une liste de tous les fichiers xml à moi. Tout fonctionne bien, sauf que les fichiers xml du répertoire racine ne sont pas inclus dans la liste.

Je comprends pourquoi, car la première chose à faire est d’obtenir les répertoires dans la racine, puis d’obtenir des fichiers, manquant ainsi l’appel GetFiles () sur la racine. J’ai essayé d’inclure l’appel GetFiles () avant le foreach, mais les résultats ne sont pas comme prévu.

public static ArrayList DirSearch(ssortingng sDir) { try { foreach (ssortingng d in Directory.GetDirectories(sDir)) { foreach (ssortingng f in Directory.GetFiles(d, "*.xml")) { ssortingng extension = Path.GetExtension(f); if (extension != null && (extension.Equals(".xml"))) { fileList.Add(f); } } DirSearch(d); } } catch (Exception ex) { Console.WriteLine(ex.Message); } return fileList; } 

Ma structure de répertoire est quelque chose comme:

 RootDirectory test1.0.xml test1.1.xml test1.2.xml 2ndLevDir test2.0.xml test2.1.xml 3rdLevDir test3.0.xml test3.1.xml 

Le code retourne:

 test2.0.xml test2.1.xml test3.0.xml test3.1.xml 

Je voudrais retourner chaque fichier, y compris:

 test1.0.xml test1.1.xml test1.2.xml 

Pas très bien verset avec récursivité. Tout pointeur serait grandement apprécié.

Vous pouvez utiliser cette surcharge de Directory.GetFiles qui recherche les sous-répertoires pour vous.

Cela retourne tous les fichiers XML de manière récursive:

 var allFiles = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories); 

Essayez la méthode suivante:

 public static IEnumerable GetXMLFiles(ssortingng directory) { List files = new List(); try { files.AddRange(Directory.GetFiles(directory, "*.xml", SearchOption.AllDirectories)); } catch (Exception ex) { Console.WriteLine(ex.Message); } return files; } 

Vous créez trois listes au lieu d’en utiliser une (vous n’utilisez pas la valeur de retour de DirSearch(d) ). Vous pouvez utiliser une liste comme paramètre pour enregistrer l’état:

 static void Main(ssortingng[] args) { var list = new List(); DirSearch(list, "."); foreach (var file in list) { Console.WriteLine(file); } } public static void DirSearch(List files, ssortingng startDirectory) { try { foreach (ssortingng file in Directory.GetFiles(startDirectory, "*.*")) { ssortingng extension = Path.GetExtension(file); if (extension != null) { files.Add(file); } } foreach (ssortingng directory in Directory.GetDirectories(startDirectory)) { DirSearch(files, directory); } } catch (System.Exception e) { Console.WriteLine(e.Message); } } 

Vous devriez avoir la boucle sur les fichiers avant ou après la boucle sur les répertoires, mais pas nesteds à l’intérieur comme vous l’avez fait.

 foreach (ssortingng f in Directory.GetFiles(d, "*.xml")) { ssortingng extension = Path.GetExtension(f); if (extension != null && (extension.Equals(".xml"))) { fileList.Add(f); } } foreach (ssortingng d in Directory.GetDirectories(sDir)) { DirSearch(d); } 

vous pouvez faire quelque chose comme ça:

 foreach (var file in Directory.GetFiles(MyFolder, "*.xml", SearchOption.AllDirectories)) { // do something with this file } 

Vous souhaitez déplacer la boucle pour les fichiers en dehors de la boucle pour les dossiers. En outre, vous devrez transmettre la structure de données contenant la collection de fichiers à chaque appel de la méthode. De cette façon, tous les fichiers entrent dans une seule liste.

 public static List DirSearch(ssortingng sDir, List files) { foreach (ssortingng f in Directory.GetFiles(sDir, "*.xml")) { ssortingng extension = Path.GetExtension(f); if (extension != null && (extension.Equals(".xml"))) { files.Add(f); } } foreach (ssortingng d in Directory.GetDirectories(sDir)) { DirSearch(d, files); } return files; } 

Alors appelle ça comme ça.

 List files = DirSearch("c:\foo", new List()); 

Mettre à jour:

Eh bien, à mon insu, jusqu’à ce que je lise l’autre réponse, il existe déjà un mécanisme intégré pour ce faire. Je vais laisser ma réponse au cas où vous souhaiteriez voir comment votre code doit être modifié pour le faire fonctionner.

Utiliser EnumerateFiles pour obtenir des fichiers dans des répertoires nesteds. Utilisez AllDirectories pour récupérer les répertoires.

 using System; using System.IO; class Program { static void Main() { // Call EnumerateFiles in a foreach-loop. foreach (ssortingng file in Directory.EnumerateFiles(@"c:\files", "*.xml", SearchOption.AllDirectories)) { // Display file path. Console.WriteLine(file); } } } 

En ce qui concerne la recherche de fichiers et de répertoires, je souhaiterais utiliser une bibliothèque .NET multithreading spécialisée qui offre de nombreuses possibilités de recherche et fonctionne très rapidement.

Toutes les informations sur la bibliothèque que vous pouvez trouver sur GitHub: https://github.com/VladPVS/FastSearchLibrary

Si vous voulez le télécharger, vous pouvez le faire ici: https://github.com/VladPVS/FastSearchLibrary/releases

Si vous avez des questions, veuillez les demander.

C’est un exemple démonstratif de la façon dont vous pouvez l’utiliser:

 class Searcher { private static object locker = new object(); private FileSearcher searcher; List files; public Searcher() { files = new List(); // create list that will contain search result } public void Startsearch() { CancellationTokenSource tokenSource = new CancellationTokenSource(); // create tokenSource to get stop search process possibility searcher = new FileSearcher(@"C:\", (f) => { return Regex.IsMatch(f.Name, @".*[Dd]ragon.*.jpg$"); }, tokenSource); // give tokenSource in constructor searcher.FilesFound += (sender, arg) => // subscribe on FilesFound event { lock (locker) // using a lock is obligatorily { arg.Files.ForEach((f) => { files.Add(f); // add the next received file to the search results list Console.WriteLine($"File location: {f.FullName}, \nCreation.Time: {f.CreationTime}"); }); if (files.Count >= 10) // one can choose any stopping condition searcher.StopSearch(); } }; searcher.SearchCompleted += (sender, arg) => // subscribe on SearchCompleted event { if (arg.IsCanceled) // check whether StopSearch() called Console.WriteLine("Search stopped."); else Console.WriteLine("Search completed."); Console.WriteLine($"Quantity of files: {files.Count}"); // show amount of finding files }; searcher.StartSearchAsync(); // start search process as an asynchronous operation that doesn't block the called thread } }