I need to perform some operations on all folders within a file share which match a defined pattern. The pattern may refer to a number of levels in the tree, e.g.
\Test\[a-z]+\Project[0-9]{3}
What is the most efficient way to traverse the tree to find all matching folders? Is there a better way to do this than a simple recursive depth first search using DirectoryInfo and di.GetDirectories(), like such:
private void TraverseSubFolder(DirectoryInfo folder)
{
if (filter.IsMatch(folder.FullName)) {
DoStuff(folder);
}
DirectoryInfo[] subFolders = folder.GetDirectories();
foreach开发者_如何转开发 (DirectoryInfo sf in subFolders)
{
TraverseSubFolder(sf);
}
}
You could use Linq to filter
Regex regex = new Regex("your regex");
var directories = Directory.GetDirectories("c:\\", null, SearchOption.AllDirectories).Where(directory => regex.IsMatch(directory));
The drawback of this approach is that it will still search into unwanted folder that were filtered out since the Where
occurs after all folders are returned.
This could be adapted.
Edit
This will not work with SearchOption.AllDirectories since as soon as you hit a folder where you have no right, UnauthorizedAccessException will be thrown.
I don't think you can go without a recursive function because of the check for UnauthorizedAccessException.
I coded this approach using Linq, but it is not very different from your own approach. At least it check for permission. It is still prone to a StackOverflowException.
private static void Traverse(List<string> folders, string rootFolder, Regex filter)
{
try
{
// Test for UnauthorizedAccessException
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, rootFolder).Demand();
Array.ForEach(Directory.GetDirectories(rootFolder),
(directory) =>
{
if (filter.IsMatch(directory))
{
folders.Add(directory);
Traverse(folders, directory, filter);
}
});
}
catch
{
// Ignore folder that we don't have access to
}
}
// Usage example
List<string> folders = new List<string>();
Regex regex = new Regex("^.+$");
Traverse(folders, "e:\\projects", regex);
Directory.GetDirectories(..,.., SearchOption.AllDirectories)
精彩评论