用 TextFieldParser 读 CSV 最稳,它能正确处理引号包裹、转义、多行字段及各种换行符;必须设 HasFieldsEnclosedInQuotes = true、显式指定编码、用 StreamReader 流式传入,避免 File.ReadAllLines 破坏逻辑。

用 TextFieldParser 读 CSV 最稳,别手写分割
直接用 string.Split(',') 解析 CSV 几乎必翻车:字段含逗号、换行、引号嵌套时会错位。.NET 自带的 Microsoft.VisualBasic.FileIO.TextFieldParser(对,VB 命名空间但 C# 可用)专为这事设计,能正确处理引号包裹、转义、多行字段。
实操建议:
- 添加引用:
Microsoft.VisualBasic程序集(.NET Core/.NET 5+ 需 NuGet 包Microsoft.VisualBasic.Core) - 必须设置
HasFieldsEnclosedInQuotes = true,否则带引号的空字段或含逗号字段会解析失败 - 调用
ReadFields()前先检查EndOfData,避免返回null导致 NullReferenceException - 编码要显式指定,比如
new StreamReader("data.csv", Encoding.UTF8),否则 BOM 或 ANSI 文件可能乱码
CSV 行末换行符不统一?TextFieldParser 默认能扛住
Windows(\r\n)、Linux(\n)、Mac(\r)混用的 CSV 文件,TextFieldParser 内部自动识别行尾,不用额外处理。但注意:如果某字段本身含 \n 且被双引号包裹(合法 CSV),它会自动合并到同一行——这是正确行为,不是 bug。
容易踩的坑:
- 手动用
File.ReadAllLines()再喂给TextFieldParser会破坏多行字段逻辑,必须用StreamReader流式传入 -
Delimiters设为new[] { "," }即可,不要加空格;加了会导致字段前/后多出空白字符 - 字段含双引号时,CSV 标准要求是两个双引号
""表示一个字面量双引号,TextFieldParser自动解码,无需手动替换
要高性能或纯 .NET Standard?选 System.Text.Json + 自定义解析器不现实,改用 CsvHelper
CsvHelper 是事实标准,支持映射到类、类型转换、自定义转换器、异步读取,且兼容 .NET Standard 2.0+。比手写快,比 TextFieldParser 更灵活,尤其适合结构固定、需强类型的场景。
关键配置点:
- 必须调用
csv.Read()后再用csv.GetRecord<t>()</t>,顺序反了会跳过首行 - 表头不在第一行?设
csv.Configuration.HasHeaderRecord = false,并手动csv.ReadHeader() - 日期/数字格式错乱?配
csv.Configuration.TypeConverterOptionsCache指定文化信息,比如new CultureInfo("zh-CN") - 大文件内存溢出?用
foreach (var record in csv.GetRecords<myclass>())</myclass>流式迭代,别全 load 进 List
遇到 MalformedLineException 或字段数不匹配?八成是编码或 BOM 问题
错误信息像 Line 12: MalformedLineException - Line is not valid,往往不是 CSV 写错了,而是文件用了 UTF-8 with BOM,而 TextFieldParser 或 CsvHelper 默认按 ANSI 或无 BOM UTF-8 解码,导致首字节 0xEF,0xBB,0xBF 被当乱码吃掉,后续全偏移。
解决方法很直接:
- 用十六进制编辑器确认是否含 BOM;有就改用
Encoding.UTF8显式构造StreamReader -
CsvHelper下,new StreamReader(stream, Encoding.UTF8)必须传入,不能只传文件路径 - 实在不确定编码?用
Ude.CharsetDetector库自动探测,但仅用于调试,生产环境应约定编码
CSV 解析真正麻烦的从来不是语法,是隐式编码、Excel 自作聪明的导出逻辑、以及人手工改保存时点错编码。盯住流怎么开、BOM 怎么处理、引号怎么嵌套,比研究语法树有用得多。











