0

I have the following code to try and get all file names in my parent directory and all its sub directories.

The code works, but not how I would like. Namely it will process all files in the parent directory and all in the "first- level" of sub directories but I want to be able to go into all levels of sub directories.

How do I do that?

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'ListBox1.Items.AddRange(IO.Directory.GetFiles("C:\"))

    For Each Dir As String In IO.Directory.GetDirectories("C:\Program Files")
        ' ListBox1.Items.Add(Dir)
        ListBox1.Items.AddRange(IO.Directory.GetFiles(Dir))
    Next
End Sub
Newd
  • 2,174
  • 2
  • 17
  • 31
LabRat
  • 1,996
  • 11
  • 56
  • 91
  • If you want to use code like that then you need to write a recursive method. If you're searching a folder that doesn't contain any inaccessible subfolders though, simply use the overload of `Directory.GetFiles` that allows you to specify searching subfolders too. It's one line of code. – jmcilhinney Jul 22 '15 at 07:08
  • 1
    @jmcilhinney In fact you don't need a recursive method... I also thought so, but I did some research and found the solution below which can be achieved with just 2 lines of code. – Xavier Peña Jul 22 '15 at 14:30
  • You would normally add the directory to your parameter list, but .NET has a built in method you can chain that will enumerate through all subdirectories for you. – ragerory Jul 22 '15 at 14:34
  • @XavierPeña, it's like you didn't even read my comment. I said that you need to use a recursive method IF you want to use code like that, i.e. a loop that examined one folder at a time. I went on to say that you could do it in one line by calling `Directory.GetFiles`. – jmcilhinney Jul 23 '15 at 00:04

1 Answers1

2

Here is the code that does what you want in just two lines:

    Dim result As List(Of String) = System.IO.Directory.GetFiles("C:\Program Files", "*", System.IO.SearchOption.AllDirectories)
    listBox1.DataSource = result

[ Credit do @Carsten in this post, which listed subdirectories and I changed to listing files and binded it to the ListBox element. I didn't know that the recursive solution was already implemented in System.IO ]

Edit1: taking comment suggestion.

Edit2: GetFiles does not allow a workaround for this problem: when you attempt to read could be configured so that the current user may not access them. More details (and solution with a recursive function) here.

Community
  • 1
  • 1
Xavier Peña
  • 7,399
  • 9
  • 57
  • 99
  • 1
    There are two issues with this solution. Firstly, why would you call `EnumerateFiles` and then call `ToList` on the result? The whole point of `EnumerateFiles` is that it returns an enumerable list so that you can keep resource utilisation low by using the items as you retrieve them. By calling `ToList` you undo that, so why would you not just call `GetFiles` instead, which returns an array in the first place? – jmcilhinney Jul 23 '15 at 00:07
  • Good point, thanks. I'm going to edit it. What's the second issue? – Xavier Peña Jul 23 '15 at 00:09
  • 1
    The second issue is that, just like `GetFiles`, `EnumerateFiles` will fail with an exception if it encounters an inaccessible folder. This is not an issue if your root folder contains no inaccessible subfolders but if you were to specify the C: drive root folder as the starting point then you'd be screwed. In situations like that, you DO need to use a recursive method, because you can then deal with each subfolder individually, ignoring inaccessible ones and continuing. – jmcilhinney Jul 23 '15 at 00:11
  • I see. I was not aware of that, when I tested the solution I used some folders that did not have that problem. Edited the solution to acknowledge this issue. Thanks for the feedback. – Xavier Peña Jul 23 '15 at 00:16