Cómo: Enumerar directorios y archivos
A partir de .NET Framework versión 4, puede enumerar directorios y archivos utilizando métodos que devuelven una colección enumerable de cadenas de sus nombres. También puede utilizar métodos que devuelven una colección enumerable de objetos DirectoryInfo, FileSystemInfo o FileInfo. En versiones anteriores de .NET Framework, solo podía obtener matrices de estas colecciones. Las colecciones enumerables proporcionan un rendimiento mejor que las matrices.
Puede utilizar igualmente colecciones enumerables obtenidas de estos métodos para proporcionar el parámetro IEnumerable<T> a los constructores de clases de colección como la clase List<T>.
Si desea obtener solo los nombres de directorios o archivos, utilice los métodos de enumeración de la clase Directory. Si desea obtener otras propiedades de directorios o archivos, utilice las clases FileSystemInfo y DirectoryInfo. Puede enumerar asimismo las líneas de un archivo de texto.
En la siguiente tabla se proporciona una guía de los métodos que devuelven colecciones enumerables.
Para enumerar |
Colección enumerable que se devuelve |
Método que se debe utilizar |
---|---|---|
Directorios |
Nombre de directorio. |
|
Información de directorio (DirectoryInfo). |
||
Archivos |
Nombres de archivos. |
|
Información de archivo (FileInfo). |
||
Información del sistema de archivos |
Entradas del sistema de archivos. |
|
Información del sistema de archivos (FileSystemInfo). |
||
Líneas de un archivo de texto |
Líneas de un archivo. |
Aunque puede enumerar inmediatamente todos los archivos de los subdirectorios de un directorio primario utilizando la opción AllDirectories, las excepciones de acceso no autorizado (UnauthorizedAccessException) pueden generar una enumeración incompleta. Si estas excepciones son posibles, puede detectarlas y continuar enumerando primero los directorios y después los archivos.
Si ejecuta Windows XP o anterior, una operación de eliminación en un archivo o un directorio que sigue una enumeración podría producir un error si permanece un identificador abierto en uno de los directorios o archivos enumerados. Si esto ocurre, debe inducir una recolección de elementos no utilizados para quitar los identificadores abiertos.
Para enumerar los nombres de directorio
Utilice el método Directory.EnumerateDirectories(String) para obtener una lista de los nombres de directorio de nivel superior en una ruta de acceso especificada.
Imports System.Collections.Generic Imports System.IO Imports System.Linq Module Module1 Sub Main() Try Dim dirPath As String = "\\archives\2009\reports" ' LINQ query. Dim dirs = From folder In _ Directory.EnumerateDirectories(dirPath) For Each folder In dirs ' Remove path information from string. Console.WriteLine("{0}", _ folder.Substring(folder.LastIndexOf("\") + 1)) Next Console.WriteLine("{0} directories found.", _ dirs.Count.ToString()) ' Optionally create a List collection. Dim workDirs As List(Of String) = New List(Of String)(dirs) Catch UAEx As UnauthorizedAccessException Console.WriteLine(UAEx.Message) Catch PathEx As PathTooLongException Console.WriteLine(PathEx.Message) End Try End Sub End Module
using System; using System.Collections.Generic; using System.IO; using System.Linq; class Program { private static void Main(string[] args) { try { string dirPath = @"\\archives\2009\reports"; // LINQ query. var dirs = from dir in Directory.EnumerateDirectories(dirPath) select dir; // Show results. foreach (var dir in dirs) { // Remove path information from string. Console.WriteLine("{0}", dir.Substring(dir.LastIndexOf("\\") + 1)); } Console.WriteLine("{0} directories found.", dirs.Count<string>().ToString()); // Optionally create a List collection. List<string> workDirs = new List<string>(dirs); } catch (UnauthorizedAccessException UAEx) { Console.WriteLine(UAEx.Message); } catch (PathTooLongException PathEx) { Console.WriteLine(PathEx.Message); } } }
Para enumerar los nombres de archivo en todos los directorios
Utilice el método Directory.EnumerateFiles(String, String, SearchOption) para buscar en todos los directorios y obtener una lista de nombres de archivo en una ruta de acceso especificada que coincidan con un modelo de búsqueda concreto.
Imports System.IO Imports System.Xml.Linq Module Module1 Sub Main() Try Dim files = From chkFile In Directory.EnumerateFiles("c:\", "*.txt", _ SearchOption.AllDirectories) From line In File.ReadLines(chkFile) Where line.Contains("Microsoft") Select New With {.curFile = chkFile, .curLine = line} For Each f In files Console.WriteLine("{0}\t{1}", f.curFile, f.curLine) Next Console.WriteLine("{0} files found.", _ files.Count.ToString()) Catch UAEx As UnauthorizedAccessException Console.WriteLine(UAEx.Message) Catch PathEx As PathTooLongException Console.WriteLine(PathEx.Message) End Try End Sub End Module
using System; using System.IO; using System.Linq; class Program { static void Main(string[] args) { try { var files = from file in Directory.EnumerateFiles(@"c:\", "*.txt", SearchOption.AllDirectories) from line in File.ReadLines(file) where line.Contains("Microsoft") select new { File = file, Line = line }; foreach (var f in files) { Console.WriteLine("{0}\t{1}", f.File, f.Line); } Console.WriteLine("{0} files found.", files.Count().ToString()); } catch (UnauthorizedAccessException UAEx) { Console.WriteLine(UAEx.Message); } catch (PathTooLongException PathEx) { Console.WriteLine(PathEx.Message); } } }
Para enumerar una colección de objetos DirectoryInfo
Utilice el método DirectoryInfo.EnumerateDirectories para obtener una colección de directorios de nivel superior.
' Create a DirectoryInfo of the Program Files directory. Dim dirPrograms As New DirectoryInfo("c:\program files") Dim StartOf2009 As New DateTime(2009, 1, 1) ' LINQ query for all directories created before 2009. Dim dirs = From dir In dirPrograms.EnumerateDirectories() Where dir.CreationTimeUtc < StartOf2009 ' Show results. For Each di As DirectoryInfo In dirs Console.WriteLine("{0}", di.Name) Next
// Create a DirectoryInfo of the Program Files directory. DirectoryInfo dirPrograms = new DirectoryInfo(@"c:\program files"); DateTime StartOf2009 = new DateTime(2009, 01, 01); // LINQ query for all directories created before 2009. var dirs = from dir in dirPrograms.EnumerateDirectories() where dir.CreationTimeUtc < StartOf2009 select new { ProgDir = dir, }; // Show results. foreach (var di in dirs) { Console.WriteLine("{0}", di.ProgDir.Name); }
Para enumerar una colección de objetos FileInfo en todos los directorios
Utilice el método DirectoryInfo.EnumerateFiles para obtener una colección de archivos que coincidan con un modelo de búsqueda especificado en todos los directorios. En este ejemplo se enumeran primero los directorios de nivel superior para detectar las posibles excepciones de acceso no autorizado y luego, los archivos.
Imports System Imports System.IO Class Program Public Shared Sub Main(ByVal args As String()) ' Create a DirectoryInfo object of the starting directory. Dim diTop As New DirectoryInfo("d:\") Try ' Enumerate the files just in the top directory. For Each fi In diTop.EnumerateFiles() Try ' Display each file over 10 MB; If fi.Length > 10000000 Then Console.WriteLine("{0}" & vbTab & vbTab & "{1}", fi.FullName, fi.Length.ToString("N0")) End If ' Catch unauthorized access to a file. Catch UnAuthTop As UnauthorizedAccessException Console.WriteLine("{0}", UnAuthTop.Message) End Try Next ' Enumerate all subdirectories. For Each di In diTop.EnumerateDirectories("*") Try ' Enumerate each file in each subdirectory. For Each fi In di.EnumerateFiles("*", SearchOption.AllDirectories) Try ' // Display each file over 10 MB; If fi.Length > 10000000 Then Console.WriteLine("{0}" & vbTab & vbTab & "{1}", fi.FullName, fi.Length.ToString("N0")) End If ' Catch unauthorized access to a file. Catch UnAuthFile As UnauthorizedAccessException Console.WriteLine("UnAuthFile: {0}", UnAuthFile.Message) End Try Next ' Catch unauthorized access to a subdirectory. Catch UnAuthSubDir As UnauthorizedAccessException Console.WriteLine("UnAuthSubDir: {0}", UnAuthSubDir.Message) End Try Next ' Catch error in directory path. Catch DirNotFound As DirectoryNotFoundException Console.WriteLine("{0}", DirNotFound.Message) ' Catch unauthorized access to a first tier directory. Catch UnAuthDir As UnauthorizedAccessException Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message) ' Catch paths that are too long. Catch LongPath As PathTooLongException Console.WriteLine("{0}", LongPath.Message) End Try End Sub End Class
using System; using System.IO; class Program { static void Main(string[] args) { // Create a DirectoryInfo object of the starting directory. DirectoryInfo diTop = new DirectoryInfo(@"d:\"); try { // Enumerate the files just in the top directory. foreach (var fi in diTop.EnumerateFiles()) { try { // Display each file over 10 MB; if (fi.Length > 10000000) { Console.WriteLine("{0}\t\t{1}", fi.FullName, fi.Length.ToString("N0")); } } // Catch unauthorized access to a file. catch (UnauthorizedAccessException UnAuthTop) { Console.WriteLine("{0}", UnAuthTop.Message); } } // Enumerate all subdirectories. foreach (var di in diTop.EnumerateDirectories("*")) { try { // Enumerate each file in each subdirectory. foreach (var fi in di.EnumerateFiles("*", SearchOption.AllDirectories)) { try { // Display each file over 10 MB; if (fi.Length > 10000000) { Console.WriteLine("{0}\t\t{1}", fi.FullName, fi.Length.ToString("N0")); } } // Catch unauthorized access to a file. catch (UnauthorizedAccessException UnAuthFile) { Console.WriteLine("UnAuthFile: {0}", UnAuthFile.Message); } } } // Catch unauthorized access to a subdirectory. catch (UnauthorizedAccessException UnAuthSubDir) { Console.WriteLine("UnAuthSubDir: {0}", UnAuthSubDir.Message); } } } // Catch error in directory path. catch (DirectoryNotFoundException DirNotFound) { Console.WriteLine("{0}", DirNotFound.Message); } // Catch unauthorized access to a first tier directory. catch (UnauthorizedAccessException UnAuthDir) { Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message); } // Catch paths that are too long. catch (PathTooLongException LongPath) { Console.WriteLine("{0}", LongPath.Message); } } }
Para quitar los identificadores abiertos en los directorios o archivos enumerados
Cree un método personalizado (o una función en Visual Basic) que contenga el código de enumeración.
Aplique el atributo MethodImplAttribute con la opción NoInlining al nuevo método. Por ejemplo:
[MethodImplAttribute(MethodImplOptions.NoInlining)] Private void Enumerate()
Incluya las llamadas a métodos siguientes, que se ejecutará después del código de enumeración:
El método GC.Collect() (sin parámetros).
El método GC.WaitForPendingFinalizers().