csv校验需用textfieldparser处理引号内逗号、tryparse防溢出、trim去bom/空行/注释,并用fieldrule类统一管理字段规则。

校验 CSV 文件字段数量是否一致
字段数不一致是最常见的数据质量问题,比如某行多了一个逗号导致解析错位。直接用 string.Split(',') 容易误判,尤其当字段本身含逗号(在引号内)时。
实操建议用 Microsoft.VisualBasic.FileIO.TextFieldParser(.NET Framework / .NET 5+ 可用),它原生支持 RFC 4180 规范:
- 启用
HasFieldsEnclosedInQuotes = true,正确处理带引号的字段 - 逐行调用
ReadFields(),检查返回数组长度是否等于预期列数 - 遇到
null返回值说明解析失败(如引号不匹配),应立即报错
别自己写正则或手动计逗号——TextFieldParser 是微软封装好的、经过验证的方案。
检测数值字段是否超出业务范围
文件里写着“1234567890123”,但数据库字段是 int,直接 int.Parse() 会抛 OverflowException,而你可能只想要日志+跳过该行。
实操建议分两步走:
- 先用
int.TryParse()或decimal.TryParse()判断是否可转为数字 - 再比对业务规则:比如订单金额必须 ≥ 0 且 ≤ 1000000,用
if (value 1_000_000) - 避免用
Convert.ToInt32()—— 它在 null 或格式错误时直接抛异常,不利于容错处理
注意:浮点类字段(如 double)要额外防 NaN 和 Infinity,double.IsNaN() 和 double.IsInfinity() 得显式检查。
识别并跳过空行、注释行和 BOM 头
用户导出的 Excel 转 CSV 常带 UTF-8 BOM(\uFEFF),首行可能是 # 导出时间:2024-05-01,或纯空行。这些不报错但会干扰字段对齐。
实操建议在读取每行后立刻清洗:
- 用
line.TrimStart('\uFEFF', '\ufeff')去掉 BOM(大小写都得覆盖) - 用
string.IsNullOrWhiteSpace(line)过滤空行 - 用
line.TrimStart().StartsWith("#")跳过注释行(注意前导空格) - 别依赖
File.ReadAllLines()后统一处理——内存压力大,且无法在读到坏行时及时中断
BOM 不是字符编码问题,是字节序标记;不清理就可能导致第一列字段名开头多出不可见字符,后续所有 .Equals("ID") 都失败。
用自定义规则类组织校验逻辑
硬编码 if/else 校验很快会失控,比如“手机号必须 11 位数字”“邮箱需匹配正则”“日期格式为 yyyy-MM-dd”。把规则散落在循环里,改一个就得翻三处。
实操建议定义一个轻量规则类:
public class FieldRule
{
public string ColumnName { get; set; }
public Func<string, bool> Validator { get; set; }
public string ErrorMessage { get; set; }
}然后按列注册:
new FieldRule { ColumnName = "Phone", Validator = s => s.Length == 11 && long.TryParse(s, out _), ErrorMessage = "手机号必须为11位数字" }- 校验时遍历规则列表,
!rule.Validator(value)就记录错误,不 throw - 规则可从 JSON 配置加载,避免每次改代码
关键点:规则函数必须是纯函数(无副作用),否则并发读文件时容易出竞态;也不要让规则里去查数据库——校验阶段只做本地判断。
真正难的不是写单条规则,是设计好字段名到规则的映射方式,以及当某行触发多个规则失败时,如何合并错误信息又不淹没关键线索。










