如何配置CsvHelper跳过无法转换类型的最后一行?
解决CsvHelper读取CSV时跳过末尾$Count行的问题
针对你遇到的CSV末尾可能存在$Count开头的无效行导致转换异常的问题,提供两种实用解决方案:
方案一:通过CsvHelper事件跳过错误行
利用CsvHelper的ReadingExceptionOccurred事件,捕获转换异常并判断是否为目标无效行,直接跳过:
using (var fs = new FileStream(@"D:\temp\csv\ALARM0_.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var reader = new StreamReader(fs)) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { // 配置异常处理:跳过$Count开头的无效行 csv.Configuration.ReadingExceptionOccurred = ex => { // 检查是否是Time_ms字段的格式错误,且当前行以$Count开头 if (ex.Exception is FormatException && csv.Context.Parser.RawRecord.StartsWith("$Count")) { return false; // 返回false表示跳过该行 } throw ex.Exception; // 其他异常正常抛出,避免隐藏问题 }; // 改用泛型方法获取新实例,避免原代码中同一实例被覆盖的问题 var records = csv.EnumerateRecords<MP370Log>().ToList(); foreach (var r in records) { // 处理每条有效记录 } }
注意:原代码中EnumerateRecords(record)会复用同一个实例,导致foreach中所有r指向同一对象,数据被覆盖。改用EnumerateRecords<MP370Log>()会自动创建新实例,解决该问题。
方案二:预读取并过滤无效行(适合小文件)
先将所有行读入内存,过滤掉$Count开头的行后再交给CsvHelper处理,避免转换异常:
var filePath = @"D:\temp\csv\ALARM0_.csv"; // 读取所有行并过滤无效行 var validLines = File.ReadAllLines(filePath) .Where(line => !line.TrimStart().StartsWith("$Count")) .ToList(); using (var stringReader = new StringReader(string.Join(Environment.NewLine, validLines))) using (var csv = new CsvReader(stringReader, CultureInfo.InvariantCulture)) { var records = csv.EnumerateRecords<MP370Log>().ToList(); foreach (var r in records) { // 处理每条有效记录 } }
适用场景:CSV文件体积较小,内存占用可接受的情况。大文件建议使用方案一,避免一次性加载所有内容到内存。
内容的提问来源于stack exchange,提问作者Álvaro García
相关产品推荐
相关产品推荐

