I came across the same problem just today. I hacked together the following code. If you want to use it in a real product you might need to improve the error handling. Since this was for a one-shot script I didn't care much.
static IEnumerable<string> EnumerateFilesRecursive(string root,string pattern="*")
{
var todo = new Queue<string>();
todo.Enqueue(root);
while (todo.Count > 0)
{
string dir = todo.Dequeue();
string[] subdirs = new string[0];
string[] files = new string[0];
try
{
subdirs = Directory.GetDirectories(dir);
files = Directory.GetFiles(dir, pattern);
}
catch (IOException)
{
}
catch (System.UnauthorizedAccessException)
{
}
foreach (string subdir in subdirs)
{
todo.Enqueue(subdir);
}
foreach (string filename in files)
{
yield return filename;
}
}
}
To use it you can either:
string[] files = EnumerateFilesRecursive(@"C:").ToArray();//Note the ToArray()
foreach (string file in files)
{
Console.WriteLine(file);
}
which first enumerates all files, stores all file names in memory and only then displays them. Alternatively you can:
IEnumerable<string> files = EnumerateFilesRecursive(@"C:");//Note that there is NO ToArray()
foreach (string file in files)
{
Console.WriteLine(file);
}
Which writes while enumerating and thus doesn't need to keep all filenames in memory at the same time.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…