C# - Obtener una lista de archivos excluyendo los que están ocultos


Directory.GetFiles() devuelve todos los archivos, incluso aquellos que están marcados como ocultos. ¿Hay alguna forma de obtener una lista de archivos que excluya los archivos ocultos?

 55
Author: Amar Palsapure, 2010-03-10

8 answers

Esto debería funcionar para usted:

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));

foreach (var f in filtered)
{
    Debug.WriteLine(f);
}
 86
Author: Austin Salonen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-06 05:33:49
// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);
 9
Author: Feedback_looper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-30 08:02:54

Usando. NET 4.0 y Directorio.EnumerateDirectories, podría usar esta construcción :

var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp")
                       let info = new FileInfo(file)
                       where (info.Attributes & FileAttributes.Hidden) == 0
                       select file;

Esto es básicamente lo mismo que la otra respuesta, excepto Directorio.EnumerateDirectories es un poco más perezoso. Sin embargo, esto no es muy útil si enumeras todo.

(El let está aquí para tener la consulta a pero más legible).

 8
Author: Jerome Laban,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-10 20:25:05

En caso de uso use:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == 0);

Esto solo encuentra ningún archivo oculto, por lo que puede usar:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

Esto es solo para leer el archivo oculto

 1
Author: jesus gilbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 15:28:00

Código de una línea:

FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => 
            (file.Attributes & FileAttributes.Hidden) == 0).ToArray();
 1
Author: Alex Jolig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 08:28:32

Si estás usando SearchOption.TopDirectoryOnly-entonces es relativamente simple, sin embargo-se vuelve mucho más complejo si desea enumerar todos los archivos recursivamente usando SearchOption.AllDirectories. Si puede obtener archivos y luego filtrar solo lectura, pero desafortunadamente no funcionará con directorios marcados como ocultos. Los archivos bajo esas carpetas también se enumeran, pero no están ocultos a diferencia del directorio.

También puedes usar GetDirectories, pero de nuevo - no puedes listar todo recursivamente usando SearchOption.AllDirectories, ya que también enumera las carpetas que residen en la carpeta oculta, pero esas carpetas no tienen el atributo oculto habilitado.

Este es el caso al menos para Tortoise svn .carpeta oculta svn. Contiene una gran cantidad de carpetas que no están ocultos, pero .svn está oculto. Finalmente he escrito la función que se ve así:

    SearchOption sopt = SearchOption.AllDirectories;
    List<String> listFiles = new List<string>();
    List<DirectoryInfo> dirs2scan = new List<DirectoryInfo>();

    dirs2scan.Add(new DirectoryInfo(fromPath) );

    for( ; dirs2scan.Count != 0; )
    {
        int scanIndex = dirs2scan.Count - 1;        // Try to preserve somehow alphabetic order which GetFiles returns 
                                                    // by scanning though last directory.
        FileInfo[] filesInfo = dirs2scan[scanIndex].GetFiles(pattern, SearchOption.TopDirectoryOnly);

        foreach (FileInfo fi in filesInfo)
        {
            if (bNoHidden && fi.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            listFiles.Add(fi.FullName);
        }

        if( sopt != SearchOption.AllDirectories )
            break;

        foreach (DirectoryInfo dir in dirs2scan[scanIndex].GetDirectories("*", SearchOption.TopDirectoryOnly))
        {
            if (bNoHidden && dir.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            dirs2scan.Add(dir);
        }
        dirs2scan.RemoveAt(scanIndex);
    }

Sopt se puede utilizar un parámetro en función si es necesario o eliminado si no es necesario.

 1
Author: TarmoPikaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 05:31:51

En realidad me gusta pasar un parámetro de función a un método que hace lo que quiero. Tengo un método SearchDirectory, que forma la base para la mayoría de las llamadas que uso:

private void SearchDirectory(DirectoryInfo startDirectory, 
                             string pattern, 
                             Action<FileInfo> act)
{
    foreach (var file in startDirectory.GetFiles(pattern))
        act(file);

    foreach (var directory in startDirectory.GetDirectories())
        SearchDirectory(directory, pattern, act);
}

private List<FileInfo> SearchDirectory(DirectoryInfo startDirectory, 
                                       string pattern, 
                                       Func<FileInfo, bool> isWanted)
{
    var lst = new List<FileInfo>();
    SearchDirectory(startDirectory, 
                    pattern, 
                    (fi) => { if (isWanted(fi)) lst.Add(fi); });
    return lst;
}

Entonces puede usar las otras soluciones listadas para escribir una función isHidden que toma un solo FileInfo, y devuelve true si es así:

private bool IsHiddenDirectory(DirectoryInfo d) {
    if (d == null) return false;
    if (d.Attributes.HasFlag(FileAttributes.Hidden))) return true;
    if (d.Parent == null) return false;
    return IsHiddenDirectory(d.Parent);
}

private bool IsHidden(FileInfo fi) {
    if ((fi.Attributes & FileAttributes.Hidden) != 0) return true;
    // If you're worried about parent directories hidden:
    return IsHiddenDirectory(fi.Directory);
    // otherwise:
    return false;
}

Entonces puedo llamarlo en otro método bastante fácilmente:

var files = SearchDirectory(new DirectoryInfo("C:\temp\"),
                            "*.xml",
                            (fi) => { return !IsHidden(fi); );
 1
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-08 13:09:20
static bool IsHidden(string p)
{
 return p.Contains("Hidden");
}

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !IsHidden(File.GetAttributes(f).ToString()));

foreach (var f in filtered)
{
 Debug.WriteLine(f);
}

Pasos:

  1. Crear bool que devuelve true cuando la cadena contiene 'Hidden' ---- static bool IsHidden(string p){return p.Contains("Hidden");}

  2. Obtener información del directorio ---- DirectoryInfo directory = new DirectoryInfo(@"C:\temp");

  3. Obtener matriz de información de archivo desde el directorio ---- FileInfo[] files = directory.GetFiles();

  4. Obtener atributos de información de archivo y convertir en cadena de la matriz de información de archivo y comprobar que contiene 'Oculto' o no ---- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));

 -1
Author: Ujjwal Kashyap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-31 01:18:30