Vorgehensweise: Abfragen der Gesamtzahl von Bytes in einem Ordnersatz (LINQ) (C#)How to: Query for the Total Number of Bytes in a Set of Folders (LINQ) (C#)

Dieses Beispiel zeigt, wie die Gesamtanzahl der Bytes, die von allen Dateien in einem angegebenen Ordner und allen Unterordnern verwendet werden, abgerufen wird.This example shows how to retrieve the total number of bytes used by all the files in a specified folder and all its subfolders.

BeispielExample

Die Sum-Methode fügt die Werte aller Elemente hinzu, die in der select-Klausel ausgewählt wurden.The Sum method adds the values of all the items selected in the select clause. Sie können diese Abfrage leicht modifizieren, um die größte oder kleinste Datei in der angegebenen Verzeichnisstruktur abzurufen, indem Sie die Min- oder Max-Methode statt der Sum-Methode verwenden.You can easily modify this query to retrieve the biggest or smallest file in the specified directory tree by calling the Min or Max method instead of Sum.

class QuerySize  
{  
    public static void Main()  
    {  
        string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\VC#";  

        // Take a snapshot of the file system.  
        // This method assumes that the application has discovery permissions  
        // for all folders under the specified path.  
        IEnumerable<string> fileList = System.IO.Directory.GetFiles(startFolder, "*.*", System.IO.SearchOption.AllDirectories);  

        var fileQuery = from file in fileList  
                        select GetFileLength(file);  

        // Cache the results to avoid multiple trips to the file system.  
        long[] fileLengths = fileQuery.ToArray();  

        // Return the size of the largest file  
        long largestFile = fileLengths.Max();  

        // Return the total number of bytes in all the files under the specified folder.  
        long totalBytes = fileLengths.Sum();  

        Console.WriteLine("There are {0} bytes in {1} files under {2}",  
            totalBytes, fileList.Count(), startFolder);  
        Console.WriteLine("The largest files is {0} bytes.", largestFile);  

        // 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 System.IO.FileInfo.Length property.  
    static long GetFileLength(string filename)  
    {  
        long retval;  
        try  
        {  
            System.IO.FileInfo fi = new System.IO.FileInfo(filename);  
            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;  
    }  
}  

Wenn Sie nur die Anzahl der Bytes in einer angegebenen Verzeichnisstruktur ermitteln wollen, können Sie dies ohne LINQ-Abfrage effizienter tun, da diese zunächst die Listenauflistung als Datenquelle erstellt, was Mehraufwand verursacht.If you only have to count the number of bytes in a specified directory tree, you can do this more efficiently without creating a LINQ query, which incurs the overhead of creating the list collection as a data source. Die Nützlichkeit des LINQ-Ansatzes wird erhöht, wenn die Abfrage komplexer wird oder wenn Sie mehrere Abfragen für dieselbe Datenquelle ausführen.The usefulness of the LINQ approach increases as the query becomes more complex, or when you have to run multiple queries against the same data source.

Die Abfrage ruft eine separate Methode auf, um die Dateilänge zu erhalten.The query calls out to a separate method to obtain the file length. Dadurch wird die mögliche Ausnahme abgefangen, die ausgelöst wird, wenn die Datei auf einem anderen Thread gelöscht wurde, nachdem das FileInfo-Objekt im Aufruf von GetFiles erstellt wurde.It does this in order to consume the possible exception that will be raised if the file was deleted on another thread after the FileInfo object was created in the call to GetFiles. Obwohl das FileInfo-Objekt bereits erstellt wurde, kann die Ausnahme auftreten, weil ein FileInfo-Objekt versucht, seine Length-Eigenschaft mit der aktuellsten Länge beim ersten Zugriff auf die Eigenschaft zu aktualisieren.Even though the FileInfo object has already been created, the exception can occur because a FileInfo object will try to refresh its Length property with the most current length the first time the property is accessed. Indem dieser Vorgang in einen Try-Catch-Block außerhalb der Abfrage erfolgt, folgt der Code der Regel zum Vermeiden von Vorgängen in Abfragen, die Nebeneffekte verursachen können.By putting this operation in a try-catch block outside the query, the code follows the rule of avoiding operations in queries that can cause side-effects. Im Allgemeinen ist beim Abfangen von Ausnahmen große Sorgfalt geboten, um sicherzustellen, dass Anwendungen nicht in einem unbekannten Zustand verbleiben.In general, great care must be taken when you consume exceptions to make sure that an application is not left in an unknown state.

Kompilieren des CodesCompiling the Code

Erstellen Sie ein Projekt, das die .NET Framework-Version 3.5 oder höher verwendet, mit einem Verweis auf System.Core.dll und using-Direktiven für System.Linq- und System.IO-Namespaces.Create a project that targets the .NET Framework version 3.5 or higher, with a reference to System.Core.dll and using directives for the System.Linq and System.IO namespaces.

Siehe auchSee Also

LINQ to Objects (C#)LINQ to Objects (C#)
LINQ und Dateiverzeichnisse (C#)LINQ and File Directories (C#)