Recursively walking through a directory tree and listing file names

22,653

Solution 1

There is a complete example on the Microsoft support site

The issue here is that you want to call DirSearch from the event handler, but it appears you're trying to define the method DirSearch inside the event handler. This is not valid.

You need to change your code as follows:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    string sourcePath = @"C:\temp\";
    this.DirSearch(sourcePath);
}

private void DirSearch(string sDir) 
{
    try 
    {
        foreach (string f in Directory.GetFiles(sDir, txtFile.Text)) 
        {
            lstFilesFound.Items.Add(f);
        }

        foreach (string d in Directory.GetDirectories(sDir)) 
        {
            this.DirSearch(d);
        }
    }
    catch (System.Exception excpt)
    {
        listBox1.Items.Add(ex.Message);
    }
}

Solution 2

Use GetDirectories() overload accepting SearchOption:

string[] dirs = Directory.GetDirectories(path, "*", SearchOption.AllDirectories))
foreach(dir)
{
    ...
}

or better EnumerateFiles():

IEnumerable<string> files = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
foreach(files)
{
    ...
}

Notice it performs lazy filesystem scan.

Share:
22,653
Steve Way
Author by

Steve Way

Updated on July 09, 2022

Comments

  • Steve Way
    Steve Way almost 2 years

    I'm trying to walk through a whole directory tree and print out all the file names on a listbox control. I wrote some code but there are errors. Not sure what I'm doing wrong. By the way, this is in C# using WPF in Visual Studio.

    Here is the whole project solution in Visual Studio: http://tinyurl.com/a2r5jv9

    Here is the code from MainWindow.xaml.cs if you don't want to download the project solution: http://pastebin.com/cWRTeq3N

    I'll paste the code here as well.

    public partial class MainWindow : Window
    {
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string sourcePath = @"C:\temp\";            
    
            static void DirSearch(string sourcePath)
            {
                try
                {
                    foreach (string d in Directory.GetDirectories(sourcePath))
                    {
                        foreach (string f in Directory.GetFiles(d))
                        {
                            listBox1.Items.Add(f);
                        }
                        DirSearch(d);
                    }
                }                      
                catch (Exception ex)
                {
                    listBox1.Items.Add(ex.Message);
                }
            }
        }
    }
    
  • Steve Way
    Steve Way over 11 years
    This is for an assignment at my university. The requirement is to use a recursive algorithm.
  • Tim Schmelter
    Tim Schmelter over 11 years
    The recursive approach has also another advantage. You can handle exceptions at the file level whereas SearchOption.AllDirectories will throw without an option to continue with the next file/directory (after logging).
  • Steve Way
    Steve Way over 11 years
    while we're on the topic, how to check for duplicate files? for example, if there are two files with the same file name in two different directories, I want to output only one file name.
  • p.s.w.g
    p.s.w.g over 11 years
    @SteveWay use if (lstFilesFound.Items.Contains(f)) { ... }.
  • Tomasz Gandor
    Tomasz Gandor over 8 years
    If you need to be eager instead of lazy, you have Directory.GetFiles (the overload with SearchOption - for recursion). I used to need this a few years ago, when there was a bug in Mono, where files were omitted when using EnumerateFiles and returned in GetFiles.