11

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); } } } } 
4
  • 2
    Method inside another method? Commented Mar 15, 2013 at 23:44
  • 1
    There seems to be a typo in your code example. Commented Mar 15, 2013 at 23:48
  • 1
    What are the exact errors? Commented Mar 15, 2013 at 23:50
  • 1
    www2.picturepush.com/photo/a/12423735/1024/Anonymous/… Commented Mar 15, 2013 at 23:59

3 Answers 3

23

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); } } 
Sign up to request clarification or add additional context in comments.

2 Comments

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.
@SteveWay use if (lstFilesFound.Items.Contains(f)) { ... }.
19

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.

3 Comments

This is for an assignment at my university. The requirement is to use a recursive algorithm.
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).
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.
0

Using reference arguments seems to be working as well. Haven't benchmarked for performance but here is my current solution.

public IEnumerable<FileInfo> GetFilesRecursive(string path) { static void GetFiles(DirectoryInfo dir, ref List<FileInfo> files) { files.AddRange(dir.GetFiles().OrderBy(f => f.Name).ToList()); foreach (var subdir in dir.GetDirectories()) { GetFiles(subdir, ref files); } } if (!Directory.Exists(path)) return Array.Empty<FileInfo>(); try { List<FileInfo> files = new(); var directory = new DirectoryInfo(path); GetFiles(directory, ref files); return files; } catch (Exception e) { throw new Exception($"Couldn't read files from directory: {path}\n", e); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.