Procedimiento para agrupar archivos por extensión (LINQ) (C#)How to group files by extension (LINQ) (C#)

En este ejemplo se muestra cómo se puede usar LINQ para efectuar operaciones avanzadas de agrupación y ordenación en listas de archivos o de carpetas.This example shows how LINQ can be used to perform advanced grouping and sorting operations on lists of files or folders. También muestra cómo paginar la salida en la ventana de consola mediante los métodos Skip y Take.It also shows how to page output in the console window by using the Skip and Take methods.

EjemploExample

En la siguiente consulta se muestra cómo agrupar el contenido de un árbol de directorio especificado por la extensión de nombre de archivo.The following query shows how to group the contents of a specified directory tree by the file name extension.

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;  
        }  
    }  
}  

La salida de este programa puede ser larga, dependiendo de los detalles del sistema de archivos local y de la configuración de startFolder.The output from this program can be long, depending on the details of the local file system and what the startFolder is set to. Para habilitar la visualización de todos los resultados, en este ejemplo se muestra cómo paginar los resultados.To enable viewing of all results, this example shows how to page through results. Se pueden aplicar las mismas técnicas a las aplicaciones web y Windows.The same techniques can be applied to Windows and Web applications. Observe que, como el código pagina los elementos en un grupo, se necesita un bucle foreach anidado.Notice that because the code pages the items in a group, a nested foreach loop is required. También hay alguna lógica adicional para calcular la posición actual en la lista y para permitir que el usuario detenga la paginación y salga del programa.There is also some additional logic to compute the current position in the list, and to enable the user to stop paging and exit the program. En este caso en concreto, la consulta de paginación se ejecuta en los resultados almacenados en caché de la consulta original.In this particular case, the paging query is run against the cached results from the original query. En otros contextos, como en LINQ to SQL, este almacenamiento en caché no es necesario.In other contexts, such as LINQ to SQL, such caching is not required.

Compilar el códigoCompiling the Code

Cree un proyecto de aplicación de consola de C# con directivas using para los espacios de nombres System.Linq y System.IO.Create a C# console application project, with using directives for the System.Linq and System.IO namespaces.

Vea tambiénSee also