I think from a code readability point of view, your best bet is to write a recursive function. A recursive function is one that calls itself, till it reaches a point where it does not need to call any other function.
To illustrate, the factorial of n, written as n! and defined to be the quantity 1 x 2 x 3 x ... x n (where n is a positive integer) can be quite easily defined in a recursive manner, as follows.
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! and 1! are defined to be 1.
Likewise, a method to enumerate all files and folder under a given path can also be defined recursively. This is because files and folders have a recursive structure.
Therefore a method such as follows, would work:
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;
}
One thing to note is that this method will "walk" the entire directory structure underneath the folder and will NOT return until it has "walked" the entire heirarchy. Therefore, it might take a long time to return, if there are many objects to be found.
Another thing to note is that the readability of this method can be further improved by using Lambda expressions and extention methods.
NB: The trouble with using Directory.GetFiles and Directory.GetDirectories to recurse sub-folders is that if there are any exceptions thrown (e.g., related to security permissions) the method will return nothing, whereas recursing manually allows one to handle those exceptions and still get a set of files back.