Практическое руководство. Группирование файлов по расширению (LINQ) (Visual Basic)

В этом примере показано, как LINQ можно использовать для выполнения расширенных операций группировки и сортировки в списках файлов или папок. В нём также показано, как странично выводить данные в окне консоли с помощью методов Skip и Take.

Пример

В следующем запросе показано, как сгруппировать содержимое указанного дерева каталогов по расширению имени файла.

Module GroupByExtension
    Public Sub Main()

        ' Root folder to query, along with all subfolders.
        Dim startFolder As String = "C:\program files\Microsoft Visual Studio 9.0\VB\"

        ' Used in WriteLine() to skip over startfolder in output lines.
        Dim rootLength As Integer = startFolder.Length

        'Take a snapshot of the folder contents
        Dim dir As New System.IO.DirectoryInfo(startFolder)
        Dim fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories)

        ' Create the query.
        Dim queryGroupByExt = From file In fileList _
                          Group By file.Extension.ToLower() Into fileGroup = Group _
                          Order By ToLower _
                          Select fileGroup

        ' Execute the query. By storing the result we can
        ' page the display with good performance.
        Dim groupByExtList = queryGroupByExt.ToList()

        ' Display one group at a time. If the number of
        ' entries is greater than the number of lines
        ' in the console window, then page the output.
        Dim trimLength = startFolder.Length
        PageOutput(groupByExtList, trimLength)

    End Sub

    ' Pages console display for large query results. No more than one group per page.
    ' This sub specifically works with group queries of FileInfo objects
    ' but can be modified for any type.
    Sub PageOutput(ByVal groupQuery, ByVal charsToSkip)

        ' "3" = 1 line for extension key + 1 for "Press any key" + 1 for input cursor.
        Dim numLines As Integer = Console.WindowHeight - 3
        ' Flag to indicate whether there are more results to display
        Dim goAgain As Boolean = True

        For Each fg As IEnumerable(Of System.IO.FileInfo) In groupQuery
            ' Start a new extension at the top of a page.
            Dim currentLine As Integer = 0

            Do While (currentLine < fg.Count())
                Console.Clear()
                Console.WriteLine(fg(0).Extension)

                ' Get the next page of results
                ' No more than one filename per page
                Dim resultPage = From file In fg _
                                Skip currentLine Take numLines

                ' Execute the query. Trim the display output.
                For Each line In resultPage
                    Console.WriteLine(vbTab & line.FullName.Substring(charsToSkip))
                Next

                ' Advance the current position
                currentLine = numLines + currentLine

                ' Give the user a chance to break out of the loop
                Console.WriteLine("Press any key for next page or the 'End' key to exit.")
                Dim key As ConsoleKey = Console.ReadKey().Key
                If key = ConsoleKey.End Then
                    goAgain = False
                    Exit For
                End If
            Loop
        Next
    End Sub
End Module

Выходные данные из этой программы могут быть длинными в зависимости от сведений о локальной файловой системе и заданном параметре startFolder . Чтобы включить просмотр всех результатов, в этом примере показано, как просмотреть результаты. Те же методы можно применять к windows и веб-приложениям. Обратите внимание, что поскольку код структурирует элементы в группе, требуется вложенный For Each цикл. Существует также некоторая дополнительная логика для вычисления текущей позиции в списке, а также для того, чтобы пользователь мог прекратить разбиение по страницам и выйти из программы. Запрос на разбиение по страницам в этом случае выполняется на кэшированных результатах исходного запроса. В других контекстах, таких как LINQ to SQL, такой кэширование не требуется.

Компиляция кода

Создайте проект консольного приложения Visual Basic с инструкцией Imports для пространства имен System.Linq.

См. также