LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

用 C# yield 封装一个CSV文件解析类,5分钟轻松处理10GB的海量数据,内存不爆,速度飞起!

admin
2025年10月27日 7:25 本文热度 18

前言

嗨,各位程序员小伙伴们,早上好!

在你的编程旅程中,有没有遇到过这样的“噩梦”场景?

“老板让我处理一个 8GB 的用户数据 CSV 文件,我一加载,电脑直接卡死!”

“这个报表要读取上百万条记录,还没处理完就 OutOfMemory 了……”

……

很熟悉的场景,是不是?

这些问题的本质是:传统方式试图把整个文件“一口吞下”,而我们的内存根本不够用。

你可能不知道,C# 为我们提供了一个优雅的解决方案——yield return。

它就像一个“懒加载”的魔法,让你可以按需生成数据,而不是一次性全部创建。

用它来处理 CSV 文件,你可以做到:

  1. 无论文件多大,内存只保存当前正在处理的一行,内存占用极低。
  2. 无需等待整个文件加载完成,解析完第一行就能立刻开始处理,启动速度快
  3. 轻松与 LINQ 结合,实现 Take()、Where()、Select() 等操作,可组合性强

今天,我们就来手把手教你用 yield 封装一个轻量级的 CSV 解析器,让你在 5 分钟内搞定 10GB 的海量数据!

准备好了吗?Let's go!

封装类

下面是封装的 CSV 解析类,核心就是 yield return 的使用,留意代码中的注释

/// <summary>
/// CSV 文件解析器
/// 使用 yield 实现惰性求值,支持流式处理海量数据
/// </summary>
publicclassCsvParser
{
    /// <summary>
    /// 解析 CSV 文件,返回一个可枚举的序列
    /// </summary>
    /// <typeparam name="T">目标对象类型</typeparam>
    /// <param name="filePath">CSV 文件路径</param>
    /// <param name="mapper">将字符串数组映射为 T 类型对象的函数</param>
    /// <returns>可枚举的 T 类型对象序列</returns>
    public IEnumerable<T> ParseCsvFile<T>(string filePath, Func<string[], T> mapper)
    {
        // 使用 StreamReader 逐行读取文件,确保资源正确释放
        usingvar reader = new StreamReader(filePath);
        
        // 读取第一行作为标题(通常 CSV 第一行是列名)
        string header = reader.ReadLine();
        Console.WriteLine($"CSV标题: {header}");
        
        string line;
        // 循环读取每一行,直到文件末尾
        while ((line = reader.ReadLine()) != null)
        {
            // 按逗号分割每一行,得到字段数组
            var fields = line.Split(',');
            
            // 简单清理字段:去除引号和首尾空格
            // 这里可根据实际业务需要进行处理
            for (int i = 0; i < fields.Length; i++)
            {
                fields[i] = fields[i].Trim('\"').Trim();
            }
            
            // 使用传入的映射函数,将字符串数组转换为业务对象
            // yield return 是关键:它不会立即返回所有数据,
            // 而是在 foreach 遍历时“按需”生成下一条数据
            yield return mapper(fields);
        }
        
        // 注意:using 语句确保 reader 在枚举结束或异常时自动关闭
    }
}

使用示例

假设有一个 User 类,用于存储用户信息:

public class User
{
    public int Id { getset; }
    public string Name { getset; }
    public string Email { getset; }
    public DateTime CreateTime { getset; }
}

现在,我们来使用 CsvParser 处理一个巨大的 CSV 文件:

// 创建解析器实例
var parser = new CsvParser();

// 解析 CSV 文件,返回一个 IEnumerable<User>
// 注意:此时文件并未完全读取,只是建立了“读取计划”
var users = parser.ParseCsvFile(@"D:\data\users.csv", fields => new User
{
    Id = int.Parse(fields[0]),
    Name = fields[1],
    Email = fields[2],
    CreateTime = DateTime.Parse(fields[3])
});

// 开始遍历!数据将逐行读取和处理
// 例如:只处理前 10 条数据(避免一次性输出太多)
foreach (var user in users.Take(10))
{
    Console.WriteLine($"用户: {user.Name}, 邮箱: {user.Email}");
}

// 可以根据实际业务需求做更多操作,比如:
// var activeUsers = users.Where(u => u.CreateTime > DateTime.Now.AddYears(-1));
// var totalUsers = users.Count(); // 注意:这会遍历整个文件

总结

我们用一个简单的 yield return,就实现了一个高效、低内存的 CSV 解析器,内存不再是瓶颈,无论文件是 10MB 还是 10GB,内存占用都几乎不变。

如果你有相类似的业务需求,不妨在你的项目试一试,相信不会让你失望的!


阅读原文:原文链接


该文章在 2025/10/29 18:58:00 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved