如何查询一组文件夹中的总字节数 (LINQ) (C#)

此示例演示如何检索由指定文件夹及其所有子文件夹中的所有文件使用的字节总数。

示例

Sum 方法可将 select 子句中选择的所有项的值相加。 可轻松修改此查询以检索指定目录树中的最大或最小文件,方法是调用 MinMax 方法,而不是 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;  
    }  
}  

如果只需对指定目录树中的字节数进行计数,则可以更高效地执行此操作而无需创建 LINQ 查询(这会产生创建列表集合作为数据源的开销)。 随着查询变得更加复杂,或者在必须对相同数据源运行多个查询时,LINQ 方法会更加有用。

查询调用单独的方法来获取文件长度。 这是为了使用在以下情况下会引发的可能异常:在 GetFiles 调用中创建了 FileInfo 对象之后,在其他线程中删除了文件。 即使已创建 FileInfo 对象,该异常也可能出现,因为 FileInfo 对象会在首次访问其 Length 属性时,尝试使用最近长度刷新该属性。 通过将此操作置于查询外部的 try-catch 块中,代码可遵循在查询中避免可能导致副作用的操作这一规则。 一般情况下,在使用异常时必须格外谨慎,以确保应用程序不会处于未知状态。

编译代码

使用 System.Linq 和 System.IO 命名空间的 using 指令创建 C# 控制台应用程序项目。

请参阅