求助:使用C# LinQ按文件扩展名分组并统计数量与总大小
问题分析与修复方案
你的代码核心问题是提前提取扩展名时丢失了原文件路径,导致计算文件大小时,用扩展名(比如txt)创建FileInfo,完全无法获取真实的文件大小。另外分组逻辑也需要调整,必须保留原文件的完整信息来统计总和。
修复后的代码
var fileGroups = files // 先为每个文件生成包含扩展名和文件信息的对象,避免重复IO操作 .Select(file => new { Extension = Path.GetExtension(file).TrimStart('.').ToLower(), FileInfo = new FileInfo(file) }) // 按处理后的扩展名分组 .GroupBy(item => item.Extension) // 计算每组的统计数据 .Select(group => new { 扩展名 = string.IsNullOrEmpty(group.Key) ? "无扩展名" : group.Key, 数量 = group.Count(), 总大小字节 = group.Sum(item => item.FileInfo.Length) }) // 按扩展名排序 .OrderBy(result => result.扩展名);
补充说明
- 避免重复IO操作:提前为每个文件创建一次
FileInfo,而非分组后重复创建,能有效提升性能。 - 处理无扩展名的文件:如果文件没有扩展名(比如
readme),Path.GetExtension会返回空字符串,这里用"无扩展名"标记,可根据需求自行调整。 - 大小单位转换:如果需要把字节转换成KB/MB等可读格式,可添加如下转换方法:
// 将字节转换为可读的文件大小格式 string FormatFileSize(long bytes) { if (bytes < 1024) return $"{bytes}B"; if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F2}KB"; return $"{bytes / (1024.0 * 1024):F2}MB"; }
之后在统计时替换为:
总大小 = FormatFileSize(group.Sum(item => item.FileInfo.Length))
示例输出(匹配你的测试列表)
假设各文件大小为:a.txt(12KB)、b.xml(8B)、c.html(10B)、d.doc(8KB)、e.txt(12KB),执行后会得到:
| 扩展名 | 数量 | 总大小 |
|---|---|---|
| txt | 2 | 24KB |
| doc | 1 | 8KB |
| html | 1 | 10B |
| xml | 1 | 8B |
内容的提问来源于stack exchange,提问作者Calvince
相关产品推荐
相关产品推荐

