views:

2210

answers:

3

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

A: 

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

rslite
+3  A: 

@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

aku
+2  A: 

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);
}
Nathan Baulch
Directory.GetDirectories returns strings, how do you get Attributes from it? :)
aku
@aku I'm using the DirectoryInfo.GetDirectories instance method, not the Directory.GetDirectories static one.
Nathan Baulch
Not as efficient/usable as creating a true recursive iterator using yield return. On big directory hierarchies using SearchOption.AllDirectories is not so good.
Ash