J'ai le code suivant pour rechercher de manière récursive des fichiers dans un répertoire, ce qui me renvoie la liste de tous les fichiers xml. Tout fonctionne bien, sauf que les fichiers XML du répertoire racine ne sont pas inclus dans la liste.
Je comprends pourquoi, puisque la première chose à faire est d’obtenir les répertoires à la racine, puis les 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 ceux que je prévois.
public static ArrayList DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, "*.xml"))
{
string 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
J'aimerais retourner tous les fichiers, y compris:
test1.0.xml
test1.1.xml
test1.2.xml
Pas très bien vers avec récurrence. Tous les indicateurs seraient grandement appréciés.
Vous pouvez utiliser cette surcharge de Directory.GetFiles qui recherche pour vous des sous-répertoires, par exemple:
string[] files = Directory.GetFiles(sDir, "*.xml", SearchOption.AllDirectories);
Une seule extension peut être recherchée comme ça, mais vous pouvez utiliser quelque chose comme:
var extensions = new List<string> { ".txt", ".xml" };
string[] files = Directory.GetFiles(sDir, "*.*", SearchOption.AllDirectories)
.Where(f => extensions.IndexOf(Path.GetExtension(f)) >= 0).ToArray();
sélectionner des fichiers avec les extensions requises (NB, sensible à la casse pour l’extension).
Dans certains cas, il peut être souhaitable d’énumérer les fichiers avec la méthode Directory.EnumerateFiles :
foreach(string f in Directory.EnumerateFiles(sDir, "*.xml", SearchOption.AllDirectories))
{
// do something
}
Consultez la documentation pour connaître les exceptions pouvant être levées, telles que UnauthorizedAccessException si le code est exécuté sous un compte ne disposant pas des autorisations d'accès appropriées.
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<string> GetXMLFiles(string directory)
{
List<string> files = new List<string>();
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 en tant que paramètre pour enregistrer l'état:
static void Main(string[] args)
{
var list = new List<string>();
DirSearch(list, ".");
foreach (var file in list)
{
Console.WriteLine(file);
}
}
public static void DirSearch(List<string> files, string startDirectory)
{
try
{
foreach (string file in Directory.GetFiles(startDirectory, "*.*"))
{
string extension = Path.GetExtension(file);
if (extension != null)
{
files.Add(file);
}
}
foreach (string 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 imbriquée à l'intérieur comme vous l'avez fait.
foreach (string f in Directory.GetFiles(d, "*.xml"))
{
string extension = Path.GetExtension(f);
if (extension != null && (extension.Equals(".xml")))
{
fileList.Add(f);
}
}
foreach (string 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 voudrez déplacer la boucle pour les fichiers en dehors de la boucle pour les dossiers. De plus, vous devrez transmettre la structure de données contenant la collection de fichiers à chaque appel de la méthode. Ainsi, tous les fichiers sont regroupés dans une seule liste.
public static List<string> DirSearch(string sDir, List<string> files)
{
foreach (string f in Directory.GetFiles(sDir, "*.xml"))
{
string extension = Path.GetExtension(f);
if (extension != null && (extension.Equals(".xml")))
{
files.Add(f);
}
}
foreach (string d in Directory.GetDirectories(sDir))
{
DirSearch(d, files);
}
return files;
}
Alors appelle ça comme ça.
List<string> files = DirSearch("c:\foo", new List<string>());
Mettre à jour:
À l'insu de moi, jusqu'à ce que je lise l'autre réponse de toute façon, il existe déjà un mécanisme intégré pour le faire. Je laisserai ma réponse au cas où vous voudriez savoir comment votre code doit être modifié pour le faire fonctionner.
Utiliser EnumerateFiles pour obtenir des fichiers dans des répertoires imbriqués. Utilisez AllDirectories pour recurse dans des répertoires.
using System;
using System.IO;
class Program
{
static void Main()
{
// Call EnumerateFiles in a foreach-loop.
foreach (string file in Directory.EnumerateFiles(@"c:\files",
"*.xml",
SearchOption.AllDirectories))
{
// Display file path.
Console.WriteLine(file);
}
}
}