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 maior arquivo.
Como recuperar o tamanho em bytes do menor arquivo.
Como recuperar o maior ou menor arquivo do objeto FileInfo de uma ou mais pastas em uma pasta raiz especificada.
Como recuperar uma sequência, como os 10 maiores arquivos.
Como ordenar os arquivos em grupos com base no tamanho do arquivo em bytes, ignorando arquivos 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 modificar facilmente esses exemplos para basear a consulta em outra propriedade do objeto FileInfo.
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 FileInfo completos, a consulta deve primeiro examinar cada um dos objetos na fonte de dados e, em seguida, classificá-los segundo o valor de sua propriedade Length. Em seguida, ela pode retornar um único elemento ou a sequência com os maiores tamanhos. Use First para retornar o primeiro elemento em uma lista. Use Take para retornar o primeiro número n de elementos. Especifique uma ordem de classificação decrescente para colocar os menores elementos no início da lista.
A consulta chama um método separado para obter o tamanho do arquivo em bytes para consumir a exceção possível que ocorrerá caso um arquivo tenha sido excluído em outro thread no período desde que o objeto FileInfo foi criado na chamada para GetFiles
. Embora o objeto FileInfo já tenha sido criado, a exceção poderá ocorrer porque um objeto FileInfo tentará atualizar sua propriedade Length usando o tamanho mais atual em bytes na primeira vez que a propriedade foi acessada. Ao colocar essa operação em um bloco try-catch fora da consulta, nós seguimos a regra de evitar operações em consultas que podem causar efeitos colaterais. Em geral, deve-se ter muito cuidado 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 instrução Imports
para o namespace System.Linq.