Pregunta

estoy usando DirectoryInfo.GetDirectories() recursivamente para encontrar todos los subdirectorios en una ruta determinada.Sin embargo, quiero excluir las carpetas del Sistema y no hay una manera clara de hacerlo.En FindFirstFile/FindNextFile las cosas estaban más claras con los atributos.

¿Fue útil?

Solución

@rslite tiene razón, .NET no ofrece ese filtrado listo para usar, pero no es difícil de implementar:

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;
        }
    }
}

Enlaces MSDN:

Propiedad FileSystemInfo.Attributes

Enumeración de atributos de archivo

Otros consejos

Este es un gran ejemplo de un escenario en el que Linq y los métodos de extensión hacen que las cosas sean realmente limpias y fáciles.

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

Si está creando una aplicación .net v2, puede usar Puente Linq para darle acceso a todos los métodos interesantes de Linq a objetos (como Where() y ToArray() arriba).

Editar

En .net v4 usarías EnumerarDirectorios en lugar de ObtenerDirectorios lo que le permite iterar sobre los resultados sin crear primero una matriz en la memoria.

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

Probablemente tendría que recorrer los resultados y rechazar aquellos con los atributos que no desea (use la propiedad Atributos).

Usando el Sweet Linq definitivo

 IEnumerable<string> directories = new DirectoryInfo(path).GetDirectories().Where(a => (a.Attributes & FileAttributes.System) == 0).Select(a => a.FullName);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top