1

I want to get all files (recursively) in my root directory / of linux OS. I am using the following code

var files = System.IO.Directory.GetFiles("/", "*", SearchOption.AllDirectories);

But its taking so much time which is making my code inefficient. Is there any way to find files recursively in much more efficient way ?

I thought of this answer but again its taking even more time than System.IO.Directory.GetFiles()

tbhaxor
  • 1,659
  • 2
  • 13
  • 43
  • 2
    Instead of using `GetFiles`, use `EnumerateFiles` which streams the results as they become available. – Camilo Terevinto Oct 16 '18 at 10:18
  • it is faster than GetFiles? if no then is there any async way ? – tbhaxor Oct 16 '18 at 10:19
  • No, it is just as slow. But, if you use something like `foreach (string file in files)`, you don't have to wait until the entire drive was searched for before starting the loop – Camilo Terevinto Oct 16 '18 at 10:20
  • @CamiloTerevinto thank u somuch – tbhaxor Oct 16 '18 at 10:25
  • `SearchOption.AllDirectories` will make it return all the files on the entire disk. That's going to be slow... It is also likely to throw exceptions when it tries to enumerate things to which you don't have access rights. – Matthew Watson Oct 16 '18 at 10:27

1 Answers1

2

I think Matthew Watson is right, whatever you do is going to work slowly because of the disc. The only thing I would try to do is do it parallely. If you have other things to do while waiting on result, maybe async is a good choiche.

using System;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Concurrent;

namespace Test
{
    class Program
    {

    static void Main(string[] args)
    {
        GetFilesOnRoot("*");            
        Console.ReadLine();
    }

    private static ConcurrentBag<string> FilesBag;
    private static void GetFilesOnRoot(string filter)
    {
        FilesBag = new ConcurrentBag<string>();
        DirectoryInfo dirRoot = new DirectoryInfo("/");
        GetDirTree(dirRoot, "*");
    }

    private static void GetDirTree(DirectoryInfo dr, string filter)
    {
        FileInfo[] files = null;
        DirectoryInfo[] subDirs = null;
        try
        {
        files = dr.GetFiles(filter + ".*");
        }
        catch(Exception) { }        

        if (files != null)
        {
        Parallel.ForEach(files, (FileInfo item) => { FilesBag.Add(item.Name); });
        subDirs = dr.GetDirectories();
        Parallel.ForEach(subDirs, (DirectoryInfo item) => { GetDirTree(item,filter); });
        }
    }

    public static async Task GetFilesOnRootAsync(string filter)
    {
        await Task.Run(() => {
        GetFilesOnRoot(filter);
        });
    }

    }
}