Vous voudrez peut-être regarder cette question où j'ai présenté un exemple de code qui utilise la récursivité pour rendre une structure de répertoire dans un TreeView. La logique devrait être la même dans la plupart des cas.
Cerebrus
5
Le problème c'est qu'il se casse très facilement si vous n'avez pas accès à un seul répertoire: pas de résultats ...
Cet article couvre tout ce dont vous avez besoin. Sauf au lieu de rechercher les fichiers et de comparer les noms, il suffit d'imprimer les noms.
Il peut être modifié comme suit:
staticvoidDirSearch(string sDir){try{foreach(string d inDirectory.GetDirectories(sDir)){foreach(string f inDirectory.GetFiles(d)){Console.WriteLine(f);}DirSearch(d);}}catch(System.Exception excpt){Console.WriteLine(excpt.Message);}}
Ajouté par barlop
GONeale mentionne que ce qui précède ne répertorie pas les fichiers dans le répertoire actuel et suggère de placer la partie de liste de fichiers en dehors de la partie qui obtient les répertoires. Ce qui suit ferait cela. Il comprend également une ligne Writeline que vous pouvez décommenter, qui aide à tracer où vous êtes dans la récursivité qui peut aider à afficher les appels pour aider à montrer comment fonctionne la récursivité.
DirSearch_ex3("c:\\aaa");staticvoidDirSearch_ex3(string sDir){//Console.WriteLine("DirSearch..(" + sDir + ")");try{Console.WriteLine(sDir);foreach(string f inDirectory.GetFiles(sDir)){Console.WriteLine(f);}foreach(string d inDirectory.GetDirectories(sDir)){DirSearch_ex3(d);}}catch(System.Exception excpt){Console.WriteLine(excpt.Message);}}
Cette méthode ne répertorie pas les fichiers pour le répertoire initial, seulement ses sous-répertoires et inférieurs. Je déplacerais GetFiles en dehors de GetDirectories
GONeale
1
Parfois, on ne veut pas les fichiers du répertoire initial, auquel cas c'est parfait pour des structures raisonnablement petites. Pour les très grandes listes, utilisez quelque chose comme la solution de Marc Gravell: stackoverflow.com/a/929418/91189
Joseph Gabriel
2
@GONeale est correct. Il est beaucoup moins plausible pour un utilisateur de ne pas s'attendre à la liste des fichiers du répertoire racine d'entrée. Le mot entrée est la clé ici. Il a été saisi pour une raison.
Florin Mircea
2
J'ai dû ajouter une prise d'essai autour de la boucle foreach intérieure sinon cela ne continue pas d'erreurs d'accès refusé
Shaun Vermaak
3
Vous devriez éviter d'attraper une exception - voudriez-vous vraiment attraper une OutOfMemoryException par exemple? N'attrapez que ce que vous pouvez gérer.
alastairtree
435
Notez que dans .NET 4.0, il existe (soi-disant) des fonctions de fichier basées sur un itérateur (plutôt que sur un tableau) intégrées:
Pour le moment, j'utiliserais quelque chose comme ci-dessous; la méthode récursive intégrée se casse trop facilement si vous n'avez pas accès à un seul sous-répertoire ...; l' Queue<string>utilisation évite trop de récursivité de la pile d'appels, et le bloc itérateur nous évite d'avoir un énorme tableau.
@soandos Sur le point de réparation récursif EnumerateFiles lève une exception IOException "Le nom du fichier ne peut pas être résolu par le système"
SerG
5
Pour tous ceux qui veulent savoir si *.*comprend également des fichiers sans extension de fichier: Oui, il a été testé il y a une minute.
Tobias Knauss
1
Pour l'utiliser, vous devrez ajouterusing System.IO;
Rétablir Monica - Au revoir SE
7
@Wikis et pour l'utiliser, Consolevous devrez ajouter using System;- mais comme l'EDI peut ajouter toutes les usingdirectives nécessaires pour vous (ctrl +.), Et puisque nous n'utilisons rien d'exotique ici, il est courant de ne pas les inclure. Heck, vous aurez également besoin d'une classdéfinition, etc. Just sayin '
Marc Gravell
1
@MarcGravell Nous sommes dans le monde .net et Visual Studio Code maintenant, donc inclure des instructions Using est toujours le bienvenu dans tout exemple de code .net pour enregistrer une série de recherches et un "rasage de yak" inutile
Comment éviter l'erreur si l'utilisateur connecté n'a pas accès à certains dossiers.
Romil Kumar Jain
5
@Romil Je ne crois pas que cet extrait de code essaie d'indiquer toutes les fonctionnalités, uniquement la fonctionnalité brute que l'OP recherchait. Merci du partage, Pescuma!
kayleeFrye_onDeck
@kayleeFrye_onDeck, je mets seulement une préoccupation au cas où il y aurait une augmentation pour l'un des dossiers lors de l'obtention des fichiers. En raison de cette préoccupation, nous implémentons notre fonction récursive personnalisée.
Romil Kumar Jain
3
Vous recevrez "UnauthorizedAccessException" avec cette solution. Vous devriez avoir une solution capable de gérer des erreurs comme celle-ci.
Kairan
13
Dans .NET 4.5, au moins, il y a cette version qui est beaucoup plus courte et a l'avantage supplémentaire d'évaluer tous les critères de fichier à inclure dans la liste:
Dans Framework 2.0, vous pouvez utiliser (il répertorie les fichiers du dossier racine, c'est la meilleure réponse la plus populaire):
staticvoidDirSearch(string dir){try{foreach(string f inDirectory.GetFiles(dir))Console.WriteLine(f);foreach(string d inDirectory.GetDirectories(dir)){Console.WriteLine(d);DirSearch(d);}}catch(System.Exception ex){Console.WriteLine(ex.Message);}}
Quelques excellentes réponses mais ces réponses n'ont pas résolu mon problème.
Dès qu'un problème d'autorisation de dossier survient: "Autorisation refusée" le code échoue. Voici ce que j'avais l'habitude de contourner le problème "Autorisation refusée":
/// <summary>/// Scans a folder and all of its subfolders recursively, and updates the List of files/// </summary>/// <param name="sFullPath">Full path of the folder</param>/// <param name="files">The list, where the output is expected</param>internalstaticvoidEnumerateFiles(string sFullPath,List<FileInfo> fileInfoList){try{DirectoryInfo di =newDirectoryInfo(sFullPath);FileInfo[] files = di.GetFiles();foreach(FileInfo file in files)
fileInfoList.Add(file);//Scan recursivelyDirectoryInfo[] 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);}}
Vous faites manuellement ce que DirectoryInfo.GetFiles () fera pour vous dès la sortie de la boîte - utilisez simplement la surcharge avec SearchOption.AllDirectories et il récurrera tout seul. C'est donc une solution compliquée .
philw
2
Je préfère utiliser DirectoryInfo car je peux obtenir des FileInfo, pas seulement des chaînes.
Pourquoi le paramètre filesest-il ref? Il n'y a pas besoin.
Massimiliano Kraus
@MassimilianoKraus Je dirais que, bien que cela ne soit pas obligatoire, il est plus clair que sa méthode va changer fileset que vous ne pouvez plus simplement donner new List<FileInfo>()comme paramètre qui serait inutile. Peut permettre une sous-optimisation et éviter de créer un nouvel objet, sauf si cela est nécessaire.
jeromej
@JeromeJ si vous savez ce qu'est la POO, vous savez que chaque fois que vous passez un objet à une méthode, cette méthode peut changer les propriétés / champs de l'objet. Donc, refcela ne clarifie rien. Le refbut est de changer le filespointeur entier même pour l'appelant de la méthode: c'est une opération dangereuse et ici il n'y a pas besoin de cela: vous pouvez simplement remplir la liste, vous n'avez pas besoin de la rediriger vers une autre liste sur le tas. refne doit être utilisé que dans des cas très particuliers; la plupart du temps, il vous suffit d'implémenter les choses de manière plus fonctionnelle.
Massimiliano Kraus
1
Pour éviter cela UnauthorizedAccessException, j'utilise:
var files =GetFiles(@"C:\","*.*",SearchOption.AllDirectories);foreach(var file in files){Console.WriteLine($"{file}");}publicstaticIEnumerable<string>GetFiles(string path,string searchPattern,SearchOption searchOption){var foldersToProcess =newList<string>(){
path
};while(foldersToProcess.Count>0){string folder = foldersToProcess[0];
foldersToProcess.RemoveAt(0);if(searchOption.HasFlag(SearchOption.AllDirectories)){//get subfolderstry{var subfolders =Directory.GetDirectories(folder);
foldersToProcess.AddRange(subfolders);}catch(Exception ex){//log if you're interested}}//get filesvar files =newList<string>();try{
files =Directory.GetFiles(folder, searchPattern,SearchOption.TopDirectoryOnly).ToList();}catch(Exception ex){//log if you're interested}foreach(var file in files){yieldreturn file;}}}
Si vous n'avez besoin que de noms de fichiers et comme je n'aimais pas vraiment la plupart des solutions ici (en termes de fonctionnalités ou de lisibilité), qu'en est-il de celle paresseuse?
privatevoidFoo(){var files =GetAllFiles("pathToADirectory");foreach(string file in files){// Use can use Path.GetFileName() or similar to extract just the filename if needed// You can break early and it won't still browse your whole disk since it's a lazy one}}/// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception>/// <exception cref="T:System.UnauthorizedAccessException">The caller does not have the required permission.</exception>/// <exception cref="T:System.IO.IOException"><paramref name="path" /> is a file name.-or-A network error has occurred.</exception>/// <exception cref="T:System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters.</exception>/// <exception cref="T:System.ArgumentNullException"><paramref name="path" /> is null.</exception>/// <exception cref="T:System.ArgumentException"><paramref name="path" /> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="F:System.IO.Path.InvalidPathChars" />.</exception>[NotNull]publicstaticIEnumerable<string>GetAllFiles([NotNull]string directory){foreach(string file inDirectory.GetFiles(directory)){yieldreturn file;// includes the path}foreach(string subDir inDirectory.GetDirectories(directory)){foreach(string subFile inGetAllFiles(subDir)){yieldreturn subFile;}}}
Voici mon point de vue à ce sujet, basé sur celui d'Hernaldo, si vous avez besoin de trouver des fichiers avec des noms d'un certain modèle, tels que des fichiers XML qui quelque part dans leur nom contiennent une chaîne particulière:
// call this like so: GetXMLFiles("Platypus", "C:\\");publicstaticList<string>GetXMLFiles(string fileType,string dir){string dirName = dir;var fileNames =newList<String>();try{foreach(string f inDirectory.GetFiles(dirName)){if((f.Contains(fileType))&&(f.Contains(".XML"))){
fileNames.Add(f);}}foreach(string d inDirectory.GetDirectories(dirName)){GetXMLFiles(fileType, d);}}catch(Exception ex){MessageBox.Show(ex.Message);}return fileNames;}
Liste des fichiers et dossiers à modéliser, implémentation personnalisée.
Cela crée une liste complète de tous les fichiers et dossiers à partir de votre répertoire de démarrage.
Celui-ci m'a aidé à obtenir tous les fichiers dans un répertoire et des sous-répertoires, peut être utile pour quelqu'un. [Inspiré des réponses ci-dessus]
staticvoidMain(string[] args){try{var root =@"G:\logs";DirectorySearch(root);}catch(Exception ex){Console.WriteLine(ex.Message);}Console.ReadKey();}publicstaticvoidDirectorySearch(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);}}}
sortie de la fonction (le contenu du dossier5 est exclu en raison de la limite de niveau et le contenu du dossier3 est exclu car il se trouve dans le tableau des dossiers exclus):
Une solution très simple, renvoie une liste de fichiers.
publicstaticList<string>AllFilesInFolder(string folder){var result =newList<string>();foreach(string f inDirectory.GetFiles(folder)){
result.Add(f);}foreach(string d inDirectory.GetDirectories(folder)){
result.AddRange(AllFilesInFolder(d));}return result;}
staticvoidMain(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();}
Réponses:
Cet article couvre tout ce dont vous avez besoin. Sauf au lieu de rechercher les fichiers et de comparer les noms, il suffit d'imprimer les noms.
Il peut être modifié comme suit:
Ajouté par barlop
GONeale mentionne que ce qui précède ne répertorie pas les fichiers dans le répertoire actuel et suggère de placer la partie de liste de fichiers en dehors de la partie qui obtient les répertoires. Ce qui suit ferait cela. Il comprend également une ligne Writeline que vous pouvez décommenter, qui aide à tracer où vous êtes dans la récursivité qui peut aider à afficher les appels pour aider à montrer comment fonctionne la récursivité.
la source
Notez que dans .NET 4.0, il existe (soi-disant) des fonctions de fichier basées sur un itérateur (plutôt que sur un tableau) intégrées:
Pour le moment, j'utiliserais quelque chose comme ci-dessous; la méthode récursive intégrée se casse trop facilement si vous n'avez pas accès à un seul sous-répertoire ...; l'
Queue<string>
utilisation évite trop de récursivité de la pile d'appels, et le bloc itérateur nous évite d'avoir un énorme tableau.la source
*.*
comprend également des fichiers sans extension de fichier: Oui, il a été testé il y a une minute.using System.IO;
Console
vous devrez ajouterusing System;
- mais comme l'EDI peut ajouter toutes lesusing
directives nécessaires pour vous (ctrl +.), Et puisque nous n'utilisons rien d'exotique ici, il est courant de ne pas les inclure. Heck, vous aurez également besoin d'uneclass
définition, etc. Just sayin 'la source
Dans .NET 4.5, au moins, il y a cette version qui est beaucoup plus courte et a l'avantage supplémentaire d'évaluer tous les critères de fichier à inclure dans la liste:
Utilisez comme ceci:
la source
la source
Dans Framework 2.0, vous pouvez utiliser (il répertorie les fichiers du dossier racine, c'est la meilleure réponse la plus populaire):
la source
Quelques excellentes réponses mais ces réponses n'ont pas résolu mon problème.
Dès qu'un problème d'autorisation de dossier survient: "Autorisation refusée" le code échoue. Voici ce que j'avais l'habitude de contourner le problème "Autorisation refusée":
J'espère que cela aide les autres.
la source
Une solution simple et propre
la source
Je préfère utiliser DirectoryInfo car je peux obtenir des FileInfo, pas seulement des chaînes.
Je le fais au cas où à l'avenir j'aurais besoin d'un filtrage futur ... basé sur les propriétés de FileInfo.
Je peux également recourir à des cordes si besoin est. (et je suis toujours à l'épreuve du temps pour les filtres / trucs de clause where.
Notez que " . " Est un modèle de recherche valide si vous souhaitez classer par extension.
la source
la source
files
est-ilref
? Il n'y a pas besoin.files
et que vous ne pouvez plus simplement donnernew List<FileInfo>()
comme paramètre qui serait inutile. Peut permettre une sous-optimisation et éviter de créer un nouvel objet, sauf si cela est nécessaire.ref
cela ne clarifie rien. Leref
but est de changer lefiles
pointeur entier même pour l'appelant de la méthode: c'est une opération dangereuse et ici il n'y a pas besoin de cela: vous pouvez simplement remplir la liste, vous n'avez pas besoin de la rediriger vers une autre liste sur le tas.ref
ne doit être utilisé que dans des cas très particuliers; la plupart du temps, il vous suffit d'implémenter les choses de manière plus fonctionnelle.Pour éviter cela
UnauthorizedAccessException
, j'utilise:la source
Si vous n'avez besoin que de noms de fichiers et comme je n'aimais pas vraiment la plupart des solutions ici (en termes de fonctionnalités ou de lisibilité), qu'en est-il de celle paresseuse?
la source
Record le plus court
la source
Voici mon point de vue à ce sujet, basé sur celui d'Hernaldo, si vous avez besoin de trouver des fichiers avec des noms d'un certain modèle, tels que des fichiers XML qui quelque part dans leur nom contiennent une chaîne particulière:
la source
Liste des fichiers et dossiers à modéliser, implémentation personnalisée.
Cela crée une liste complète de tous les fichiers et dossiers à partir de votre répertoire de démarrage.
Méthode:
Usage:
la source
Solution courte et simple
la source
Celui-ci m'a aidé à obtenir tous les fichiers dans un répertoire et des sous-répertoires, peut être utile pour quelqu'un. [Inspiré des réponses ci-dessus]
la source
la source
Une version améliorée avec max lvl pour descendre dans le répertoire et option pour exclure les dossiers:
répertoire d'entrée:
sortie de la fonction (le contenu du dossier5 est exclu en raison de la limite de niveau et le contenu du dossier3 est exclu car il se trouve dans le tableau des dossiers exclus):
la source
Voici une version du code de B. Clay Shannon non statique pour les fichiers Excel:
la source
Une solution très simple, renvoie une liste de fichiers.
la source
la source