0

I am trying to return a list of type FileInfo by searching an arbitrary directory recursively. However, in my main() method, when I check to see the count of FoundFiles, it is 0 meaning I returned an empty object. See Code below:

using System;
using System.IO;
using System.Collections.Generic;

class FindExtensions
{  
    private static List<FileInfo> SearchFileSystem(DirectoryInfo DirInfo, List<FileInfo> FileList)
    {
        List<FileInfo> FileInfoList = new List<FileInfo>();
        try
        {
            foreach (DirectoryInfo SubdirInfo in DirInfo.GetDirectories())
            {
                SearchFileSystem(SubdirInfo, FileList);
            }
        }
        catch
        {
            // do some stuff
        }
        try
        {
            foreach (FileInfo File in DirInfo.GetFiles())
            {
                FileInfoList.Add(File);
            }
        }
        catch
        {
            // do some stuff
        }


        foreach (FileInfo f in FileInfoList)
        {
            Console.WriteLine(f.FullName);
        }

        return FileInfoList;

    }

    static void Main()
    {

        DirectoryInfo dir_info = new DirectoryInfo(@"C:\<whatever>");
        List<FileInfo> file_list = new List<FileInfo>();

        List<FileInfo> FoundFiles = SearchFileSystem(dir_info, file_list);

        Console.WriteLine("Count is: " + FoundFiles.Count);

        //^^^^ this returns 0...why is it empty?

        Console.WriteLine("This is the debug mode. Press key to restart");
        Console.ReadKey();
    }
}

I added a for loop in the SearchFileSystem method to check the contents of FileInfoList before I return it, and it will contain files. However, it contains nothing in main. I'm new to the nuances of C#, so apologies if this is quite easy.

Also, it is worth noting that if I use type List with string instead of FileInfo, this works just fine. Hoping to use a List of type FileInfo if possible.

Thanks.

corneria
  • 608
  • 3
  • 11
  • 24

2 Answers2

2

You are not adding the results from recursive calls. So ideally you are getting the results from only the last directory which may not have some files.. Try this:

foreach (DirectoryInfo SubdirInfo in DirInfo.GetDirectories())
            {
                FileInfoList.AddRange(SearchFileSystem(SubdirInfo, FileList));
            }
Piyush Parashar
  • 866
  • 8
  • 20
  • Good call. I wasn't looking at where I was storing the data. Making my List a global variable did the trick for now. – corneria Nov 21 '14 at 05:18
1

Why not just use the GetFiles() method and let it do the work for you

static void Main()
{

    DirectoryInfo dir_info = new DirectoryInfo(@"C:\<whatever>");
    List<FileInfo> file_list = new List<FileInfo>();

    //This will add all the files in all directories. You can customize the search from here as well.
    file_list.AddRange(dir_info.GetFiles("*", SearchOption.AllDirectories));
    Console.WriteLine("Count is: " + file_list.Count);

    //^^^^ this returns 0...why is it empty?

    Console.WriteLine("This is the debug mode. Press key to restart");
    Console.ReadKey();
}

But! In answer to your question, you are calling List<FileInfo> FoundFiles = new List<FileInfo>(); every time you call SearchFileSystem(...). Then you call the method recursively but don't use any of the results from there.

If you want to use your existing code, here are the necessary changes I'd make:

private static void SearchFileSystem(DirectoryInfo DirInfo, List<FileInfo> FileList)
{
    try
    {
        foreach (DirectoryInfo SubdirInfo in DirInfo.GetDirectories())
        {
            SearchFileSystem(SubdirInfo, FileList);
        }
    }
    catch
    {
        // do some stuff
    }

    //Since we are passing in FileList, let's use it instead of a new list.
    try
    {
        foreach (FileInfo File in DirInfo.GetFiles())
        {
            FileList.Add(File);
        }
    }
    catch
    {
        // do some stuff
    }


    foreach (FileInfo f in FileList)
    {
        Console.WriteLine(f.FullName);
    }
}

static void Main()
{

    DirectoryInfo dir_info = new DirectoryInfo(@"C:\<whatever>");
    List<FileInfo> file_list = new List<FileInfo>();

    SearchFileSystem(dir_info, file_list);

    Console.WriteLine("Count is: " + FoundFiles.Count);

    //^^^^ this returns 0...why is it empty?

    Console.WriteLine("This is the debug mode. Press key to restart");
    Console.ReadKey();
}
techvice
  • 1,315
  • 1
  • 12
  • 24
  • I should have stated it above, but I have to account for files that the user running the program will have unauthorized access to. Hence, the recursive strategy. I'll Use the AddRange method though. – corneria Nov 21 '14 at 05:17
  • 1
    @PiyushParashar Objects are defaulted to pass by reference in C#. Only with structs do you need to explicitly state that you passing by ref or out. It's not a bad idea for objects as well because it states intention but for very simplistic code like this I usually skip. – techvice Nov 21 '14 at 05:28