Thursday, July 28, 2011

C# recursive file counter

I am constantly surprised with how easy .NET makes things sometimes. I needed a quick recursive file counter output to a report, and was able to write this in just a few minutes, using some new methods available in .NET 4 (EnumerateFiles/Directories) (UPDATE: not sure what I was thinking here - .GetFiles()/.GetDirectories() provides pretty much the same thing - array vs. generic list):

static void Main(string[] args)
   string startingDir = @"C:\files";
   string reportFile = @"C:\file_count.txt";

   using (StreamWriter report = new StreamWriter(reportFile))
        countFiles(startingDir, report);

private static void countFiles(string dir, StreamWriter report) {
   DirectoryInfo directory = new DirectoryInfo(dir);
   IEnumerable<FileInfo> files = directory.EnumerateFiles();
   IEnumerable<DirectoryInfo> dirs = directory.EnumerateDirectories();

   report.WriteLine(String.Format("{0}: {1}", dir, files.Count()));

   foreach (var d in dirs)
        countFiles(d.FullName, report);

It works very quickly (100,000 files in as much as 8 directories deep in less than 30 seconds on a modest machine), and couldn't have been more straightforward to write.

BTW, if all you need is just a total file count, this works well:

DirectoryInfo d = new DirectoryInfo(startingDir);
int totalCount = d.EnumerateFiles("*.*", SearchOption.AllDirectories).Count();

After thinking about this some more, I wonder if this may even be easier/more efficient with LINQ. I've got to try that for fun, and check the performance of each.