Como: Enumerar os diretórios e arquivos
Começando com o .NET Framework versão 4, você pode enumerar os diretórios e arquivos usando métodos que retornam uma coleção de enumerable de seqüências de caracteres de seus nomes. Você também pode usar os métodos que retornam uma coleção de enumerable de DirectoryInfo, FileInfo, ou FileSystemInfo objetos. Nas versões anteriores do.NET Framework, só foi possível obter matrizes dessas coleções. Coleções enumeráveis fornecem um desempenho melhor do que os arrays.
Você também pode usar as coleções enumeráveis obtidas a partir desses métodos para fornecer a IEnumerable<T> parâmetro para construtores de coleção de classes, como o List<T> classe.
Se você quiser obter apenas os nomes dos diretórios ou arquivos, use os métodos de enumeração da Directory classe. Se você desejar obter outras propriedades de diretórios ou arquivos, use o DirectoryInfo e FileSystemInfo classes. Você também pode enumerar as linhas de um arquivo de texto.
A tabela a seguir fornece um guia para os métodos que retornam coleções enumeráveis.
Enumerar |
Coleção enumerável para retornar |
Método a ser usado |
---|---|---|
Diretórios |
Nomes de diretório. |
|
Informações de diretório (DirectoryInfo). |
||
Files |
Nomes de arquivo. |
|
Informações sobre o arquivo (FileInfo). |
||
Informações do sistema de arquivo |
Entradas de sistema de arquivo. |
|
Informações do sistema de arquivos (FileSystemInfo). |
||
Linhas de um arquivo de texto |
Linhas de um arquivo. |
Embora você imediatamente pode enumerar todos os arquivos nos subdiretórios de um diretório pai usando o AllDirectories de opção exceções de acesso não autorizado (UnauthorizedAccessException) pode causar a enumeração estar incompleto. Se essas exceções são possíveis, você pode capturá-las e continuar enumerando primeiro os diretórios e enumerando os arquivos.
Se você estiver executando o Windows XP ou anterior, uma operação de exclusão em um arquivo ou diretório que segue uma enumeração pode falhar se houver um identificador aberto que permanece em um dos arquivos ou diretórios enumerados. Se isso estiver ocorrendo, você deve induzir a uma coleta de lixo para remover os identificadores abertos.
Para enumerar os nomes de diretório
Use o Directory.EnumerateDirectories(String) método para obter uma lista dos nomes de diretório de nível superior em um caminho de especificado.
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 os nomes de arquivo em todos os diretórios
Use o Directory.EnumerateFiles(String, String, SearchOption) método para pesquisar todos os diretórios para obter uma lista de nomes de arquivo em um caminho especificado que correspondam a um padrão de pesquisa especificados.
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 uma coleção de objetos de DirectoryInfo
Use o DirectoryInfo.EnumerateDirectories método para obter uma coleção de pastas de nível 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 uma coleção de objetos de FileInfo em todos os diretórios
Use o DirectoryInfo.EnumerateFiles método para obter uma coleção de arquivos que correspondam a um padrão de pesquisa especificados em todos os diretórios. Este exemplo primeiro enumera os diretórios de nível superior para capturar exceções de possíveis de acesso não autorizado e, em seguida, enumera os arquivos.
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 remover os identificadores abertos em arquivos ou diretórios enumerados
Crie um personalizado método (ou função em Visual Basic) para conter o código de enumeração.
Aplicar o MethodImplAttribute de atributo com o NoInlining opção para o novo método. Por exemplo:
[MethodImplAttribute(MethodImplOptions.NoInlining)] Private void Enumerate()
Incluem as seguintes chamadas de método executar após o seu código de enumeração:
O GC.Collect() método (sem parâmetros).
O método GC.WaitForPendingFinalizers().