Je pense que d'un point de vue de la lisibilité du code, votre meilleur pari est d'écrire une fonction récursive . Une fonction récursive est une fonction qui s'appelle elle-même, jusqu'à ce qu'elle atteigne un point où elle n'a plus besoin d'appeler une autre fonction. Pour illustrer, la factorielle de n, écrite comme n! et défini comme étant la quantité 1 x 2 x 3 x ... x n (où n est un entier positif) peut être assez facilement défini d'une manière récursive, comme suit.
public int factorial(int n)
{
if (n < 0)
{
throw new Exception("A factorial cannot be calculated for negative integers.");
}
if (n == 0 || n == 1)
{
// end condition, where we do not need to make a recursive call anymore
return 1;
}
else
{
// recursive call
return n * factorial(n - 1);
}
}
NB: 0! et 1! sont définis comme 1.
De même, une méthode permettant d'énumérer tous les fichiers et dossiers sous un chemin donné peut également être définie de manière récursive. C'est parce que les fichiers et les dossiers ont une structure récursive.
Par conséquent, un tel procédé comme suit, fonctionnerait:
public static List<FileSystemInfo> GetAllFilesAndFolders(string folder)
{
// NOTE : We are performing some basic sanity checking
// on the method's formal parameters here
if (string.IsNullOrEmpty(folder))
{
throw new ArgumentException("An empty string is not a valid path.", "folder");
}
if (!Directory.Exists(folder))
{
throw new ArgumentException("The string must be an existing path.", "folder");
}
List<FileSystemInfo> fileSystemInfos = new List<FileSystemInfo>();
try
{
foreach (string filePath in Directory.GetFiles(folder, "*.*"))
{
// NOTE : We will add a FileSystemInfo object for each file found
fileSystemInfos.Add(new FileInfo(filePath));
}
}
catch
{
// NOTE : We are swallowing all exceptions here
// Ideally they should be surfaced, and at least logged somewhere
// Most of these will be security/permissions related, i.e.,
// the Directory.GetFiles method will throw an exception if it
// does not have security privileges to enumerate files in a folder.
}
try
{
foreach (string folderPath in Directory.GetDirectories(folder, "*"))
{
// NOTE : We will add a FileSystemInfo object for each directory found
fileSystemInfos.Add(new DirectoryInfo(folderPath));
// NOTE : We will also add all FileSystemInfo objects found under
// each directory we find
fileSystemInfos.AddRange(GetAllFilesAndFolders(folderPath));
}
}
catch
{
// NOTE : We are swallowing all exceptions here
// Ideally they should be surfaced, and at least logged somewhere
// Most of these will be security/permissions related, i.e.,
// the Directory.GetDirectories method will throw an exception if it
// does not have security privileges to enumerate files in a folder.
}
return fileSystemInfos;
}
Une chose à noter est que cette méthode « marcher » la structure de répertoire entier sous le dossier et ne reviendra pas jusqu'à ce qu'il ait " marché "toute la hiérarchie. Par conséquent, il peut prendre beaucoup de temps à retourner, s'il y a beaucoup d'objets à trouver.
Une autre chose à noter est que la lisibilité de cette méthode peut être améliorée en utilisant des expressions Lambda et des méthodes d'extension. NB: Le problème avec l'utilisation de Directory.GetFiles et de Directory.GetDirectories pour recopier des sous-dossiers est que s'il y a des exceptions levées (par exemple, liées à des autorisations de sécurité), la méthode ne retournera rien, alors que récursive manuellement permet de gérer ces exceptions et toujours récupérer un ensemble de fichiers.
Ajouté "Using .NET 3.0", à la question. –