Partilhar via


Como: Consulta para o maior arquivo ou arquivos em uma árvore de diretório (LINQ)

Este exemplo mostra cinco consultas relacionadas à dimensionar do arquivo em bytes:

  • Como recuperar o dimensionar em bytes de arquivo maior.

  • Como recuperar o dimensionar em bytes de arquivo menor.

  • Como recuperar o FileInfo objeto maior ou menor arquivo de uma ou mais pastas em uma pasta raiz especificada.

  • sistema autônomo recuperar uma sequência de sistema autônomo sistema autônomo 10 maiores arquivos.

  • Como a ordem de arquivos em grupos com base em suas dimensionar do arquivo em bytes, ignorando arquivos menores que um dimensionar especificado.

Exemplo

O exemplo a seguir contém cinco consultas separadas que mostram como consultar e arquivos de agrupar, dependendo do dimensionar do arquivo em bytes.Você pode modificar com com facilidade esses exemplos para basear a consulta em alguma Outros 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"

        Dim fileList = GetFiles(root)

        ' 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 GetFiles(root) _
                         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

    ' Function to retrieve a list of files. Note that this is a copy
    ' of the file information.
    Function GetFiles(ByVal root As String) As System.Collections.Generic.IEnumerable(Of System.IO.FileInfo)
        Return From file In My.Computer.FileSystem.GetFiles _
                  (root, FileIO.SearchOption.SearchAllSubDirectories, "*.*") _
               Select New System.IO.FileInfo(file)
    End Function
End Module
class QueryBySize
{
    static void Main(string[] args)
    {
        QueryFilesBySize();
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }

    private static void QueryFilesBySize()
    {
        string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";

        // Take a snapshot of the file system. 
        // fileList is an IEnumerable<System.IO.FileInfo>
        var fileList = GetFiles(startFolder);

        //Return the size of the largest file
        long maxSize =
            (from file in fileList
             let len = GetFileLength(file)
             select len)
             .Max();

        Console.WriteLine("The length of the largest file under {0} is {1}",
            startFolder, maxSize);

        // Return the FileInfo object for the largest file
        // by sorting and selecting from beginning of list
        System.IO.FileInfo longestFile = 
            (from file in fileList
            let len = GetFileLength(file)
            where len > 0
            orderby len descending
            select file)
            .First();

        Console.WriteLine("The largest file under {0} is {1} with a length of {2} bytes",
                            startFolder, longestFile.FullName, longestFile.Length);

        //Return the FileInfo of the smallest file
        System.IO.FileInfo smallestFile = 
            (from file in fileList
            let len = GetFileLength(file)
            where len > 0
            orderby len ascending
            select file).First();

        Console.WriteLine("The smallest file under {0} is {1} with a length of {2} bytes",
                            startFolder, smallestFile.FullName, smallestFile.Length);

        //Return the FileInfos for the 10 largest files
        // queryTenLargest is an IEnumerable<System.IO.FileInfo>
        var queryTenLargest = 
            (from file in fileList
            let len = GetFileLength(file)
            orderby len descending
            select file).Take(10);

        Console.WriteLine("The 10 largest files under {0} are:", startFolder);

        foreach (var v in queryTenLargest)
        {
            Console.WriteLine("{0}: {1} bytes", v.FullName, v.Length);
        }


        // Group the files according to their size, leaving out
        // files that are less than 200000 bytes. 
        var querySizeGroups = 
            from file in fileList
            let len = GetFileLength(file)
            where len > 0
            group file by (len / 100000) into fileGroup
            where fileGroup.Key >= 2
            orderby fileGroup.Key descending
            select fileGroup;


        foreach (var filegroup in querySizeGroups)
        {
            Console.WriteLine(filegroup.Key.ToString() + "00000");
            foreach (var item in filegroup)
            {
                Console.WriteLine("\t{0}: {1}", item.Name, item.Length);
            }
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

    // This method is used to swallow the possible exception
    // that can be raised when accessing the FileInfo.Length property.
    // In this particular case, it is safe to swallow the exception.
    static long GetFileLength(System.IO.FileInfo fi)
    {
        long retval;
        try
        {
            retval = fi.Length;
        }
        catch (System.IO.FileNotFoundException)
        {
            // If a file is no longer present,
            // just add zero bytes to the total.
            retval = 0;
        }
        return retval;
    }

    // This method assumes that the application has discovery 
    // permissions for all folders under the specified path.
    static IEnumerable<System.IO.FileInfo> GetFiles(string path)
    {
        if (!System.IO.Directory.Exists(path))
            throw new System.IO.DirectoryNotFoundException();

        string[] fileNames = null;
        List<System.IO.FileInfo> files = new List<System.IO.FileInfo>();

        fileNames = System.IO.Directory.GetFiles(path, "*.*", System.IO.SearchOption.AllDirectories);
        foreach (string name in fileNames)
        {
            files.Add(new System.IO.FileInfo(name));
        }
        return files;
    }
}

Para retornar um ou mais completa FileInfo objetos, primeiro a consulta deve examinar cada um dos dados de fonte e, em seguida, classificá-los pelo valor de sua propriedade length. Em seguida, ele pode retornar um único ou a sequência com comprimento maior.Use First para retornar o primeiro elemento em uma lista. Use Take<TSource> para retornar o primeiro n número de elementos. Especifica uma ordem de classificar decrescente para colocar os elementos menores no início da lista.

A consulta chama um método separado para obter o dimensionar do arquivo em bytes para consumir a exceção possível que será gerada no caso em que um arquivo foi excluído em outro thread no período de time desde o FileInfo objeto foi criado na telefonar para GetFiles. Mesmo durante o FileInfo objeto já foi criado, a exceção pode ocorrer porque um FileInfo objeto irá tentar correnteizar seu Length propriedade usando a maioria dos atuais dimensionar em bytes do primeiro time a propriedade for acessada. Ao colocar esta operação em um bloco try-catch fora da consulta, seguimos a regra de evitar operações em consultas que podem causar efeitos colaterais.Em geral, ótimo deve ter cuidado ao consumir exceções, para certificar-se de que um aplicativo não for deixado em estado desconhecido.

Compilando o código

  • Criar um Visual Studio projeto que se destina a .NET Framework versão 3.5. O projeto tem uma referência a sistema.Core.dll e um using diretiva (translation from VPE for Csharp) ou Imports demonstrativo)Visual Basic) para o namespace sistema.LINQ por padrão.

  • Copie este código para seu projeto.

  • Pressione F5 para compilar e executar o programa.

  • Pressione qualquer tecla para sair da janela do console.

Programação robusta

Para operações de consulta intensivo sobre o Sumário de vários tipos de documentos e arquivos, considere usar o Windows área de trabalho Pesquisar mecanismo.

Consulte também

Conceitos

LINQ para Objetos

O LINQ e arquivo diretórios