Udostępnij za pośrednictwem


Porady: grupowanie plików według rozszerzenia (LINQ)

W tym przykładzie przedstawiono sposób LINQ można wykonywać zaawansowane grupowanie i sortowanie operacji na listach plików lub folderów.On również pokazuje, jak strony danych wyjściowych w oknie konsoli przy użyciu Skip``1 i Take``1 metody.

Przykład

Następująca kwerenda pokazuje, jak grupa zawartość drzewa katalogu określonego przez rozszerzenie nazwy pliku.

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 diplay 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 diplay 
        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
class GroupByExtension
{
    // This query will sort all the files under the specified folder 
    //  and subfolder into groups keyed by the file extension. 
    private static void Main()
    {
        // Take a snapshot of the file system. 
        string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\Common7";

        // Used in WriteLine to trim output lines. 
        int trimLength = startFolder.Length;

        // Take a snapshot of the file system.
        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

        // This method assumes that the application has discovery permissions 
        // for all folders under the specified path.
        IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

        // Create the query. 
        var queryGroupByExt =
            from file in fileList
            group file by file.Extension.ToLower() into fileGroup
            orderby fileGroup.Key
            select fileGroup;

        // 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.
        PageOutput(trimLength, queryGroupByExt);
    }

    // This method specifically handles group queries of FileInfo objects with string keys. 
    // It can be modified to work for any long listings of data. Note that explicit typing 
    // must be used in method signatures. The groupbyExtList parameter is a query that produces 
    // groups of FileInfo objects with string keys. 
    private static void PageOutput(int rootLength,
                                    IEnumerable<System.Linq.IGrouping<string, System.IO.FileInfo>> groupByExtList)
    {
        // Flag to break out of paging loop. 
        bool goAgain = true;

        // "3" = 1 line for extension + 1 for "Press any key" + 1 for input cursor.
        int numLines = Console.WindowHeight - 3;

        // Iterate through the outer collection of groups. 
        foreach (var filegroup in groupByExtList)
        {
            // Start a new extension at the top of a page. 
            int currentLine = 0;

            // Output only as many lines of the current group as will fit in the window. 
            do
            {
                Console.Clear();
                Console.WriteLine(filegroup.Key == String.Empty ? "[none]" : filegroup.Key);

                // Get 'numLines' number of items starting at number 'currentLine'. 
                var resultPage = filegroup.Skip(currentLine).Take(numLines);

                //Execute the resultPage query 
                foreach (var f in resultPage)
                {
                    Console.WriteLine("\t{0}", f.FullName.Substring(rootLength));
                }

                // Increment the line counter.
                currentLine += numLines;

                // Give the user a chance to escape.
                Console.WriteLine("Press any key to continue or the 'End' key to break...");
                ConsoleKey key = Console.ReadKey().Key;
                if (key == ConsoleKey.End)
                {
                    goAgain = false;
                    break;
                }
            } while (currentLine < filegroup.Count());

            if (goAgain == false)
                break;
        }
    }
}

Dane wyjściowe z tego programu może być długi, w zależności od tego, szczegóły dotyczące lokalnego systemu plików i startFolder jest ustawiona na.Aby włączyć wyświetlanie wszystkich wyników, w tym przykładzie przedstawiono sposób przeglądania wyników.Te same techniki, mogą być stosowane do systemu Windows i aplikacji sieci Web.Warto zauważyć, że ponieważ kod strony elementów w grupie zagnieżdżonych foreach pętli jest wymagany.Jest również pewne dodatkowe logiki obliczyć bieżącą pozycję na liście i umożliwić użytkownikowi zatrzymać stronicowania i zakończyć pracę z programem.W tym szczególnym przypadku stronicowania uruchamiana jest kwerenda buforowane wyniki z oryginalnej kwerendy.W innych kontekstach takich jak LINQ do SQL, takie buforowanie nie jest wymagane.

Kompilowanie kodu

  • Tworzenie Visual Studio projekt, który jest przeznaczony dla .NET Framework w wersji 3.5.Domyślnie projekt zawiera odwołanie do System.Core.dll i using dyrektywy (C#) lub Imports instrukcji (Visual Basic) dla obszaru nazw System.Linq.W języku C# projektów, należy dodać using dyrektywa obszaru nazw System.IO.

  • Skopiuj ten kod do projektu.

  • Naciśnij klawisz F5, aby skompilować i uruchomić program.

  • Naciśnij dowolny klawisz, aby zamknąć okno konsoli.

Stabilne programowanie

Kwerendy intensywnych operacji nad zawartość wielu rodzajów dokumentów i plików, należy rozważyć użycie Wyszukiwanie z pulpitu systemu Windows silnika.

Zobacz też

Koncepcje

LINQ do obiektów

LINQ i katalogi plików