8
\$\begingroup\$

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 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<string> SearchSubdirs(string currentDir, int currentDepth) {
 IEnumerable<string> 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 < maxDepth) {
 IEnumerable<string> 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;
 }
 }
 }
}
asked Mar 5, 2013 at 17:08
\$\endgroup\$
2

1 Answer 1

5
+50
\$\begingroup\$

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<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;
}
answered Mar 13, 2013 at 11:30
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.