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





Вероятно, вам придется просмотреть результаты и отклонить те, с атрибутами, которые вам не нужны (используйте свойство Attributes).
@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:
Это отличный пример сценария, в котором методы 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, вы можете использовать LinqBridge, чтобы предоставить вам доступ ко всем классным методам Linq to objects (например, Where () и ToArray () выше).
Редактировать
В .net v4 вы должны использовать EnumerateDirectories вместо GetDirectories, что позволяет вам перебирать результаты без предварительного создания массива в памяти.
public static IEnumerable<DirectoryInfo> EnumerateNonSystemDirectories(
this DirectoryInfo directory,
string searchPattern,
SearchOption searchOption)
{
return directory.EnumerateDirectories(searchPattern, searchOption)
.Where(subDir => (subDir.Attributes & FileAttributes.System) == 0);
}
@aku Я использую метод экземпляра DirectoryInfo.GetDirectories, а не статический метод Directory.GetDirectories.
Не так эффективно / удобно, как создание настоящего рекурсивного итератора с использованием yield return. В больших иерархиях каталогов использование SearchOption.AllDirectories не так хорошо.
Использование совершенного Sweet Linq
IEnumerable<string> directories = new DirectoryInfo(path).GetDirectories().Where(a => (a.Attributes & FileAttributes.System) == 0).Select(a => a.FullName);
Directory.GetDirectories возвращает строки, как получить из него атрибуты? :)