debugcsharpMinor
Simplifying exception handling on Enumerators
Viewed 0 times
handlingexceptionsimplifyingenumerators
Problem
I have a files search function that iterates over a given directory until a given depth is reached and returns the found files. I did this via the Enumerate methods of the Directory class and yield return the results. Since it's very likely that I hit a directory that I can't access (e.g. system directories) or generate a too long path (if the depth is large), I have to catch the exceptions from these cases. However since I can't use
Is there a better/shorter way to do this, or are there best practices for that case?
yield in try/catch statements, I find my code pretty bloated, because I have to seperate the critical method calls from the rest.Is there a better/shorter way to do this, or are there best practices for that case?
private IEnumerable SearchSubdirs(string currentDir, int currentDepth) {
IEnumerable exeFiles;
try {
exeFiles = Directory.EnumerateFiles(currentDir, "*.exe");
}
catch (UnauthorizedAccessException uae) {
Debug.WriteLine(uae.Message);
yield break;
}
catch (PathTooLongException ptle) {
Debug.WriteLine(ptle.Message);
yield break;
}
foreach (string currentFile in exeFiles) {
// Ignore unistaller *.exe files
if (currentFile.IndexOf("unins", 0, StringComparison.CurrentCultureIgnoreCase) == -1) {
yield return currentFile;
}
}
if (currentDepth subDirectories;
currentDepth++;
try {
subDirectories = Directory.EnumerateDirectories(currentDir);
}
catch (UnauthorizedAccessException uae) {
Debug.WriteLine(uae.Message);
yield break;
}
catch (PathTooLongException ptle) {
Debug.WriteLine(ptle.Message);
yield break;
}
foreach (string subDir in subDirectories) {
foreach (string file in SearchSubdirs(subDir, currentDepth)) {
yield return file;
}
}
}
}Solution
I would use Linq methods to simplify the code. Also I've extracted 2 methods to simplify the main method. And please rename
GetFilesWeAreLookingFor to whatever your find appropriate :).private static IEnumerable GetFilesWeAreLookingFor(string currentDir)
{
try
{
return Directory.EnumerateFiles(currentDir, "*.exe")
.Where(fileName => fileName.IndexOf("unins", 0, StringComparison.CurrentCultureIgnoreCase) == -1);
}
catch (UnauthorizedAccessException uae)
{
Debug.WriteLine(uae.Message);
}
catch (PathTooLongException ptle)
{
Debug.WriteLine(ptle.Message);
}
return Enumerable.Empty();
}
private IEnumerable GetNestedFiles(string currentDir, int nestedDepth)
{
try
{
return Directory.EnumerateDirectories(currentDir)
.SelectMany(subDirectory => SearchSubdirs(subDirectory, nestedDepth));
}
catch (UnauthorizedAccessException uae)
{
Debug.WriteLine(uae.Message);
}
catch (PathTooLongException ptle)
{
Debug.WriteLine(ptle.Message);
}
return Enumerable.Empty();
}
private IEnumerable SearchSubdirs(string currentDir, int currentDepth)
{
IEnumerable filesWeAreLookingFor = GetFilesWeAreLookingFor(currentDir);
if (currentDepth < _maxDepth)
filesWeAreLookingFor = filesWeAreLookingFor.Concat(GetNestedFiles(currentDir, currentDepth + 1));
return filesWeAreLookingFor;
}Code Snippets
private static IEnumerable<string> GetFilesWeAreLookingFor(string currentDir)
{
try
{
return Directory.EnumerateFiles(currentDir, "*.exe")
.Where(fileName => fileName.IndexOf("unins", 0, StringComparison.CurrentCultureIgnoreCase) == -1);
}
catch (UnauthorizedAccessException uae)
{
Debug.WriteLine(uae.Message);
}
catch (PathTooLongException ptle)
{
Debug.WriteLine(ptle.Message);
}
return Enumerable.Empty<string>();
}
private IEnumerable<string> GetNestedFiles(string currentDir, int nestedDepth)
{
try
{
return Directory.EnumerateDirectories(currentDir)
.SelectMany(subDirectory => SearchSubdirs(subDirectory, nestedDepth));
}
catch (UnauthorizedAccessException uae)
{
Debug.WriteLine(uae.Message);
}
catch (PathTooLongException ptle)
{
Debug.WriteLine(ptle.Message);
}
return Enumerable.Empty<string>();
}
private IEnumerable<string> SearchSubdirs(string currentDir, int currentDepth)
{
IEnumerable<string> filesWeAreLookingFor = GetFilesWeAreLookingFor(currentDir);
if (currentDepth < _maxDepth)
filesWeAreLookingFor = filesWeAreLookingFor.Concat(GetNestedFiles(currentDir, currentDepth + 1));
return filesWeAreLookingFor;
}Context
StackExchange Code Review Q#23494, answer score: 5
Revisions (0)
No revisions yet.