Я думаю, с точки зрения читабельности кода, вам лучше всего написать рекурсивную функцию. Рекурсивная функция - это та, которая вызывает сама себя, пока не достигнет точки, когда ей не нужно вызывать никакую другую функцию.
Чтобы проиллюстрировать факториал n, записанный как n! и определенная как величина 1 x 2 x 3 x ... x n (где n - положительное целое число), может быть довольно легко определена рекурсивным способом следующим образом.
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);
}
}
Примечание: 0! и 1! определены как 1.
Аналогично, метод для перечисления всех файлов и папок по заданному пути также может быть определен рекурсивно. Это потому, что файлы и папки имеют рекурсивную структуру.
Поэтому такой метод будет работать:
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;
}
Следует отметить, что этот метод «обходит» всю структуру каталогов под папкой и НЕ возвращает, пока не «обходит» всю иерархию. Поэтому для возврата может потребоваться много времени, если найдено много объектов.
Следует также отметить, что читаемость этого метода может быть улучшена с помощью лямбда-выражений и методов расширения.
NB. Проблема с использованием Directory.GetFiles и Directory.GetDirectories для рекурсии подпапок заключается в том, что при возникновении каких-либо исключений (например, связанных с разрешениями безопасности) метод не возвращает ничего, тогда как рекурсивное выполнение вручную позволяет обработать его вручную. эти исключения и по-прежнему получить набор файлов обратно.