Question

I am using DirectoryInfo.GetDirectories() recursively to find the all the sub-directories under a given path. However, I want to exclude the System folders and there is no clear way for that. In FindFirstFile/FindNextFile things were clearer with the attributes.

Was it helpful?

Solution

@rslite is right, .NET doesn't give such filtering out-of-box, but it's not hard to implement:

static IEnumerable<string> GetNonSystemDirs(string path)
{
    var dirs = from d in Directory.GetDirectories(path)
               let inf = new DirectoryInfo(d)
               where (inf.Attributes & FileAttributes.System) == 0
               select d;

    foreach (var dir in dirs)
    {
        yield return dir;
        foreach (var subDir in GetNonSystemDirs(dir))
        {
            yield return subDir;
        }
    }
}

MSDN links:

FileSystemInfo.Attributes Property

FileAttributes Enumeration

OTHER TIPS

This is a great example of a scenario where Linq and extension methods make things really clean and easy.

public static DirectoryInfo[] GetNonSystemDirectories(
    this DirectoryInfo directory,
    string searchPattern,
    SearchOption searchOption)
{
    return directory.GetDirectories(searchPattern, searchOption)
        .Where(subDir => (subDir.Attributes & FileAttributes.System) == 0)
        .ToArray();
}

If you're building a .net v2 application, then you can use LinqBridge to give you access to all the cool Linq to objects methods (like Where() and ToArray() above).

Edit

In .net v4 you'd use EnumerateDirectories instead of GetDirectories which allows you to iterate over the results without building an array in memory first.

public static IEnumerable<DirectoryInfo> EnumerateNonSystemDirectories(
    this DirectoryInfo directory,
    string searchPattern,
    SearchOption searchOption)
{
    return directory.EnumerateDirectories(searchPattern, searchOption)
        .Where(subDir => (subDir.Attributes & FileAttributes.System) == 0);
}

You'd probably have to loop through the results and reject those with the attributes that you don't want (use the Attributes property).

Using the ultimate Sweet Linq

 IEnumerable<string> directories = new DirectoryInfo(path).GetDirectories().Where(a => (a.Attributes & FileAttributes.System) == 0).Select(a => a.FullName);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top