Searching for file in directories recursively

Paul picture Paul · Mar 22, 2012 · Viewed 154.4k times · Source

I have the following code to recursively search for files through a directory, which returns a list of all xml files to me. All works well, except that xml files in the root directory are not included in the list.

I understand why, since the first thing it does is get the directories in the root, then get files, thus missing the GetFiles() call on the root. I tried including the GetFiles() call prior to the foreach, but the results are not as I expect.

public static ArrayList DirSearch(string sDir)
{
    try
    {
        foreach (string d in Directory.GetDirectories(sDir))
        {
            foreach (string f in Directory.GetFiles(d, "*.xml"))
            {
                string extension = Path.GetExtension(f);
                if (extension != null && (extension.Equals(".xml")))
                {
                fileList.Add(f);
                }
            }
            DirSearch(d);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return fileList;
}

My directory structure is something like:

RootDirectory
        test1.0.xml
            test1.1.xml
            test1.2.xml
  2ndLevDir
            test2.0.xml
            test2.1.xml
  3rdLevDir
               test3.0.xml
               test3.1.xml

Code returns:

test2.0.xml
test2.1.xml
test3.0.xml
test3.1.xml

I would like to return every file including:

test1.0.xml
test1.1.xml
test1.2.xml

Not very well verse with recursion. Any pointers would be greatly appreciated.

Answer

Andrew Morton picture Andrew Morton · Mar 22, 2012

You could use this overload of Directory.GetFiles which searches subdirectories for you, for example:

string[] files = Directory.GetFiles(sDir, "*.xml", SearchOption.AllDirectories);

Only one extension can be searched for like that, but you could use something like:

var extensions = new List<string> { ".txt", ".xml" };
string[] files = Directory.GetFiles(sDir, "*.*", SearchOption.AllDirectories)
                    .Where(f => extensions.IndexOf(Path.GetExtension(f)) >= 0).ToArray();

to select files with the required extensions (N.B. that is case-sensitive for the extension).


In some cases it can be desirable to enumerate over the files with the Directory.EnumerateFiles Method:

foreach(string f in Directory.EnumerateFiles(sDir, "*.xml", SearchOption.AllDirectories))
{
    // do something
}

Consult the documentation for exceptions which can be thrown, such as UnauthorizedAccessException if the code is running under an account which does not have appropriate access permissions.