简体   繁体   中英

How can i get all files on disk with a specific extension using 'Directory.getFiles' and save them in a list

I'm doing a console project whose goal is to search the entire disk for all files with the extension '.config'

I've tried something like:

foreach (string file in Directory.GetFiles("C:\\", "*.config", SearchOption.AllDirectories))
  {
   Console.WriteLine(file);
   Console.ReadLine();
}

but gave me an error "denied access to path (...)".

On the internet I found this code:

Stack<string> pending = new Stack<string>();
        pending.Push("C:\\");

        while (pending.Count != 0)
        {
            var path = pending.Pop();
            string[] next = null;

            try
            {
                next = Directory.GetFiles(path, "*.config");
            }
            catch { }

            if (next != null && next.Length != 0)
                foreach (var file in next)
                {
                    Console.WriteLine(file);
                    Console.ReadLine();
                }
            try
            {
                next = Directory.GetDirectories(path);
                foreach (var subdir in next) pending.Push(subdir);
            }
            catch { }
        }

but it just shows the path clicking always in 'enter' and I want to save those files/path in a list.

Someone can help?

Replace the lines

Console.WriteLine(file);
Console.ReadLine();

with a method to store them in a list.
For example

foundFiles.Add(file);

Then when the method is done, you can read all found file paths from this list.

Notes:
This will not yield all files on the system that match the filter.
Only files where your application has access to their respective directory are found this way.
For example the Windows directory and user directories of other users are usually protected. (assuming you run on Windows)

Keep in mind, that some files might be protected independently of their directory.
So when trying to read them, also consider the fact, that the read might fail.
Just encompass the read with a try catch.

There are two things you can do to improve that code:

  1. Use Directory.EnumerateFiles() and Directory.EnumerateDirectories() to avoid making a copy of the names of all the files in each directory.
  2. Make the return type of the method IEnumerable<string> to make it easier to consume.

We also need to be very careful about exceptions caused by attempting to access protected files and directories. The code below is also complicated by the fact that you're not allowed to yield return from inside a try/catch block, so we have to rearrange the code somewhat.

(Also note that we have to dispose the enumerator returned from .GetEnumerator() ; normally this is done automatically when you use foreach , but in this case we can't - because of having to avoid doing yield return in a try/catch - so we have to use using to dispose it.)

Here's a modification of your original code to do this:

public static IEnumerable<string> GetFiles(string root, string spec)
{
    var pending = new Stack<string>(new []{root});

    while (pending.Count > 0)
    {
        var path = pending.Pop();
        IEnumerator<string> fileIterator = null;

        try
        {
            fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
        }

        catch {}

        if (fileIterator != null)
        {
            using (fileIterator)
            {
                while (true)
                {
                    try
                    {
                        if (!fileIterator.MoveNext()) // Throws if file is not accessible.
                            break;
                    }

                    catch { break; }

                    yield return fileIterator.Current;
                }
            }
        }

        IEnumerator<string> dirIterator = null;

        try
        {
            dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
        }

        catch {}

        if (dirIterator != null)
        {
            using (dirIterator)
            {
                while (true)
                {
                    try
                    {
                        if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
                            break;
                    }

                    catch { break; }

                    pending.Push(dirIterator.Current);
                }
            }
        }
    }
}

As an example, here's how you could use a console app to list all the accessible ".txt" files on the "C:\\" drive:

static void Main()
{
    foreach (var file in GetFiles("C:\\", "*.txt"))
    {
        Console.WriteLine(file);
    }
}

关于错误“拒绝访问路径(...)”,有时您必须以管理员身份运行Visual Studio才能访问C:\\驱动器中的某些文件夹。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM