Вопрос

Я использую DirectoryInfo.GetDirectories() рекурсивно найти все подкаталоги по заданному пути.Однако я хочу исключить системные папки, и для этого нет четкого способа.В FindFirstFile/FindNextFile с атрибутами было проще.

Это было полезно?

Решение

@rslite прав, .NET не предоставляет такой фильтрации из коробки, но реализовать ее несложно:

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:

Свойство FileSystemInfo.Attributes

Перечисление FileAttributes

Другие советы

Это отличный пример сценария, в котором Linq и методы расширения делают работу действительно простой и понятной.

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

Если вы создаете приложение .net v2, вы можете использовать ЛинкБридж чтобы предоставить вам доступ ко всем замечательным методам Linq to object (например, Where() и ToArray() выше).

Редактировать

В .net v4 вы бы использовали ПеречислитьКаталоги вместо Получить каталоги что позволяет вам перебирать результаты без предварительного создания массива в памяти.

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

Вероятно, вам придется просмотреть результаты и отклонить результаты с ненужными атрибутами (используйте свойство Attributes).

Использование идеального Sweet Linq

 IEnumerable<string> directories = new DirectoryInfo(path).GetDirectories().Where(a => (a.Attributes & FileAttributes.System) == 0).Select(a => a.FullName);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top