Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

c# - Enumerating Files Throwing Exception

I am trying to enumerate through files on my computer using the below code but everytime it hits a file or dir that I don't have permission to read it throws an exception. Is there any way I can continue searching after the exception has been thrown? I know some people have had similar issues but is there any other way of doing this other than checking every file/folder individually?

try
{
    string[] files = Directory.GetFiles(@"C:", *.*",SearchOption.AllDirectories);
    foreach (string file in files)
    {
       Console.WriteLine(file);
    }
}
catch
{
}

Thanks for any help as this is driving me mad!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I came across the same problem just today. I hacked together the following code. If you want to use it in a real product you might need to improve the error handling. Since this was for a one-shot script I didn't care much.

static IEnumerable<string> EnumerateFilesRecursive(string root,string pattern="*")
{
    var todo = new Queue<string>();
    todo.Enqueue(root);
    while (todo.Count > 0)
    {
        string dir = todo.Dequeue();
        string[] subdirs = new string[0];
        string[] files = new string[0];
        try
        {
            subdirs = Directory.GetDirectories(dir);
            files = Directory.GetFiles(dir, pattern);
        }
        catch (IOException)
        {
        }
        catch (System.UnauthorizedAccessException)
        {
        }

        foreach (string subdir in subdirs)
        {
            todo.Enqueue(subdir);
        }
        foreach (string filename in files)
        {
            yield return filename;
        }
    }
}

To use it you can either:

string[] files = EnumerateFilesRecursive(@"C:").ToArray();//Note the ToArray()
foreach (string file in files)
{
   Console.WriteLine(file);
}

which first enumerates all files, stores all file names in memory and only then displays them. Alternatively you can:

IEnumerable<string> files = EnumerateFilesRecursive(@"C:");//Note that there is NO ToArray()
foreach (string file in files)
{
   Console.WriteLine(file);
}

Which writes while enumerating and thus doesn't need to keep all filenames in memory at the same time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...