C # – Obtenga una lista de archivos, excluidos los que están ocultos

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

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); } 
 // check whether a file is hidden bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden); 

Usando .NET 4.0 y Directory.EnumerateDirectories, podrías 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 Directory.EnumerateDirectories es un poco más vago. Sin embargo, esto no es muy útil si enumeras todo.

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

si uso uso:

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

esto solo no encuentra un archivo oculto, así que puedes usar:

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

esto es solo para leer el archivo oculto

Código de una línea:

 FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => (file.Attributes & FileAttributes.Hidden) == 0).ToArray(); 

Si está utilizando SearchOption.TopDirectoryOnly, entonces es relativamente simple, sin embargo, se vuelve mucho más complejo si desea listar 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 debajo de esas carpetas también se incluyen en la lista, pero no están ocultos a diferencia del directorio.

También puede usar GetDirectories, pero nuevamente, no puede enumerar todo recursivamente utilizando SearchOption.AllDirectories, ya que también enumera las carpetas que se encuentran en la carpeta oculta, pero esas carpetas no tienen habilitado el atributo oculto.

Este es el caso al menos para la carpeta oculta Tortoise svn .svn. Contiene muchas carpetas que no están ocultas, pero .svn está oculto. Finalmente, escribí una función que se ve así:

  SearchOption sopt = SearchOption.AllDirectories; List listFiles = new List(); List dirs2scan = new List(); 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 puede usarse un parámetro en la función si es necesario o eliminarse si no es necesario.

De hecho, prefiero pasar un parámetro de función a un método que hace lo que yo 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 act) { foreach (var file in startDirectory.GetFiles(pattern)) act(file); foreach (var directory in startDirectory.GetDirectories()) SearchDirectory(directory, pattern, act); } private List SearchDirectory(DirectoryInfo startDirectory, string pattern, Func isWanted) { var lst = new List(); SearchDirectory(startDirectory, pattern, (fi) => { if (isWanted(fi)) lst.Add(fi); }); return lst; } 

Luego puede usar las otras soluciones listadas para escribir una función IsHidden que toma un solo FileInfo, y devuelve verdadero 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); ); 
 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 verdadero 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 la matriz de información de archivo del directorio —- FileInfo[] files = directory.GetFiles();

  4. obtener información del archivo Atributos y convertir en cadena desde la matriz de información del archivo y comprobar que contiene ‘Oculto’ o no —- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));