简体   繁体   中英

How can i ignore access denied when searching to get all sub directories?

static IEnumerable<string> GetSubdirectoriesContainingOnlyFiles(string path)
{
    try
    {
        return from subdirectory in Directory.GetDirectories(path, "*", SearchOption.AllDirectories)
               where Directory.GetDirectories(subdirectory).Length == 0
               select subdirectory;
    }
    catch
    {

    }
}

In this case i'm searching in c:\\ So some directories are access denied. I added try and catch but now this method dosent have a return.

And how or should i handle at all it when it's getting to the catch ? I want in the end to get a List of all sub directories so i can get all sub directories names and the Length(the number of sub directories).

UPDATE

I tried this in the class constructor:

if (m_pars.SearchDir != null)
{
    ApplyAllFiles(m_pars.SearchDir,ProcessFile);
}

m_pars.SearchDir in this contain C:\\

Then in ApplyAllFiles:

static List<string> allsubdirs = new List<string>();
static void ProcessFile(string path) {/* ... */}
public static void ApplyAllFiles(string folder, Action<string> fileAction)
{
    foreach (string file in Directory.GetFiles(folder))
    {
        fileAction(file);
    }
    foreach (string subDir in Directory.GetDirectories(folder))
    {
        try
        {
            ApplyAllFiles(subDir, fileAction);
            allsubdirs.Add(subDir);
        }
        catch
        {
            // swallow, log, whatever
        }
    }
}

But the List allsubdirs is empty.

Your problem might be that you don't visit (add to the list) the current directory before recursively visiting its subdirectories. So if you get an exception there, nothing will be added to the list.

The following works for me. (I've also made it a bit more generic by using callbacks and made the exception handling stricter.)

class DirectoryHelper
{
    public static void Test()
    {
        DirectoryHelper.EnumerateSubDirectories(@"c:\windows\system32");
    }

    public static List<string> EnumerateSubDirectories(string path)
    {
        // Depending on your use case, it might be 
        // unecessary to save these in memory 
        List<string> allSubdirs = new List<string>();
        EnumerateSubDirectories(path,
            filePath => Console.WriteLine("Visited file: " + filePath),
            dirPath => allSubdirs.Add(dirPath),
            noAccessPath => Console.WriteLine("No access: " + noAccessPath)
        );
        return allSubdirs;
    }

    private static void EnumerateSubDirectories(string root, Action<string> fileAction, Action<string> subdirAction, Action<string> noAccessAction)
    {
        foreach (string file in Directory.GetFiles(root))
        {
            fileAction(file);
        }

        foreach (string dir in Directory.GetDirectories(root))
        {
            try
            {
                subdirAction(dir);
                EnumerateSubDirectories(dir, fileAction, subdirAction, noAccessAction);
            }
            catch (UnauthorizedAccessException)
            {
                noAccessAction(dir);
            }
        }
    }
}

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