DirectoryInfo.GetDirectories() и атрибуты
-
01-07-2019 - |
Вопрос
Я использую 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:
Другие советы
Это отличный пример сценария, в котором 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);