Partilhar via


Como consultar o maior arquivo ou arquivos em uma árvore de diretório (LINQ) (Visual Basic)

Este exemplo mostra cinco consultas relacionadas ao tamanho do arquivo em bytes:

  • Como recuperar o tamanho em bytes do arquivo maior.

  • Como recuperar o tamanho em bytes do menor arquivo.

  • Como obter o maior ou menor arquivo do objeto FileInfo de uma ou mais pastas sob uma pasta raiz especificada.

  • Como recuperar uma sequência como os 10 maiores arquivos.

  • Como ordenar arquivos em grupos com base em seu tamanho em bytes, ignorando arquivos que são menores do que um tamanho especificado.

Exemplo

O exemplo a seguir contém cinco consultas separadas que mostram como consultar e agrupar arquivos, dependendo do tamanho do arquivo em bytes. Você pode facilmente modificar esses exemplos para basear a consulta em alguma outra propriedade do FileInfo objeto.

Module QueryBySize  
    Sub Main()  
  
        ' Change the drive\path if necessary  
        Dim root As String = "C:\Program Files\Microsoft Visual Studio 9.0"  
  
        'Take a snapshot of the folder contents  
        Dim dir As New System.IO.DirectoryInfo(root)  
        Dim fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories)  
  
        ' Return the size of the largest file  
        Dim maxSize = Aggregate aFile In fileList Into Max(GetFileLength(aFile))  
  
        'Dim maxSize = fileLengths.Max  
        Console.WriteLine("The length of the largest file under {0} is {1}", _  
                          root, maxSize)  
  
        ' Return the FileInfo object of the largest file  
        ' by sorting and selecting from the beginning of the list  
        Dim filesByLengDesc = From file In fileList _  
                              Let filelength = GetFileLength(file) _  
                              Where filelength > 0 _  
                              Order By filelength Descending _  
                              Select file  
  
        Dim longestFile = filesByLengDesc.First  
  
        Console.WriteLine("The largest file under {0} is {1} with a length of {2} bytes", _  
                          root, longestFile.FullName, longestFile.Length)  
  
        Dim smallestFile = filesByLengDesc.Last  
  
        Console.WriteLine("The smallest file under {0} is {1} with a length of {2} bytes", _  
                                root, smallestFile.FullName, smallestFile.Length)  
  
        ' Return the FileInfos for the 10 largest files  
        ' Based on a previous query, but nothing is executed  
        ' until the For Each statement below.  
        Dim tenLargest = From file In filesByLengDesc Take 10  
  
        Console.WriteLine("The 10 largest files under {0} are:", root)  
  
        For Each fi As System.IO.FileInfo In tenLargest  
            Console.WriteLine("{0}: {1} bytes", fi.FullName, fi.Length)  
        Next  
  
        ' Group files according to their size,  
        ' leaving out the ones under 200K  
        Dim sizeGroups = From file As System.IO.FileInfo In fileList _  
                         Where file.Length > 0 _  
                         Let groupLength = file.Length / 100000 _  
                         Group file By groupLength Into fileGroup = Group _  
                         Where groupLength >= 2 _  
                         Order By groupLength Descending  
  
        For Each group In sizeGroups  
            Console.WriteLine(group.groupLength + "00000")  
  
            For Each item As System.IO.FileInfo In group.fileGroup  
                Console.WriteLine("   {0}: {1}", item.Name, item.Length)  
            Next  
        Next  
  
        ' Keep the console window open in debug mode  
        Console.WriteLine("Press any key to exit.")  
        Console.ReadKey()  
  
    End Sub  
  
    ' This method is used to catch the possible exception  
    ' that can be raised when accessing the FileInfo.Length property.  
    ' In this particular case, it is safe to ignore the exception.  
    Function GetFileLength(ByVal fi As System.IO.FileInfo) As Long  
        Dim retval As Long  
        Try  
            retval = fi.Length  
        Catch ex As FileNotFoundException  
            ' If a file is no longer present,  
            ' just return zero bytes.
            retval = 0  
        End Try  
  
        Return retval  
    End Function  
End Module  

Para retornar um ou mais objetos completos FileInfo , a consulta primeiro deve examinar cada um na fonte de dados e, em seguida, classificá-los pelo valor de sua propriedade Length. Em seguida, pode retornar o elemento único ou a sequência com o maior comprimento. Use First para retornar o primeiro elemento de uma lista. Use Take para retornar o primeiro n número de elementos. Especifique uma ordem de classificação decrescente para colocar os menores elementos no início da lista.

A consulta invoca um método distinto para obter o tamanho do arquivo em bytes a fim de lidar com a possível exceção que será gerada caso um arquivo tenha sido eliminado em outro thread no período de tempo desde que o objeto FileInfo foi criado quando foi feita a chamada para GetFiles. Mesmo que o FileInfo objeto já tenha sido criado, a exceção pode ocorrer porque um FileInfo objeto tentará atualizar sua Length propriedade usando o tamanho mais atual em bytes na primeira vez que a propriedade for acessada. Ao colocar esta operação num bloco try-catch fora da consulta, seguimos a regra de evitar operações em consultas que possam causar efeitos secundários. Em geral, muito cuidado deve ser tomado ao consumir exceções, para garantir que um aplicativo não seja deixado em um estado desconhecido.

Compilar o código

Crie um projeto de aplicativo de console do Visual Basic, com uma Imports instrução para o namespace System.Linq.

Ver também