读取CSV时中文变问号是因未指定UTF-8编码,Windows下Encoding.Default默认为GBK,导致UTF-8文件解码错位;应显式用Encoding.UTF8构造StreamReader或StreamWriter(写入时设BOM),TextFieldParser也须传入Encoding.UTF8参数。

读取CSV时中文变问号,大概率是没指定编码
Windows系统下用 Encoding.Default 读CSV,表面能跑通,实际会把UTF-8格式的文件当GBK解码,中文直接变 ???。这不是文件损坏,是解码错位——就像用粤语听普通话广播,字都认识但意思全错。
- 绝大多数现代CSV(尤其从Excel、Python pandas或网页导出)默认是UTF-8,不含BOM
-
Encoding.Default在简体中文Windows上等于GBK,和UTF-8不兼容 - 别信“打开不乱码就说明编码对”,记事本自动探测BOM或启发式判断,
StreamReader不会
用 StreamReader 显式指定 Encoding.UTF8
这是最轻量、最可控的方式,绕过系统默认编码陷阱。关键不是“选对”,而是“强制指定”。
- 构造
StreamReader时必须传入Encoding.UTF8,不能依赖无参构造函数 - 如果CSV带BOM(开头三个字节
EF BB BF),Encoding.UTF8能自动识别;不带BOM也照常解码 - 避免用
File.ReadAllLines(path)—— 它内部用的就是Encoding.Default,无声崩坏
using (var reader = new StreamReader(path, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// 按逗号分割、处理字段...
}
}
写入CSV时加BOM防Excel双击乱码
Excel双击打开UTF-8 CSV时,经常显示乱码,不是它错了,是它没看到BOM,误判成ANSI。解决方案不是换编码,是补BOM。
- 用
new StreamWriter(path, false, new UTF8Encoding(true))—— 第三个参数true表示写入BOM - 别用
Encoding.UTF8直接传入(它默认BOM为false),否则Excel依然懵 - 如果目标是跨平台工具(如VS Code、LibreOffice),BOM非必需;但只要涉及Excel双击打开,BOM就是刚需
用 TextFieldParser 时编码必须显式传参
Microsoft.VisualBasic.FileIO.TextFieldParser 好用但藏坑:它的构造函数看似支持编码,但重载不明确,容易掉进默认编码陷阱。
- 必须用带
Encoding参数的构造函数:new TextFieldParser(stream, Encoding.UTF8) - 千万别用
new TextFieldParser(path)—— 它走的是Encoding.Default - 注意它不接受
string路径直接传入编码,得先用File.OpenRead+StreamReader包一层再传流
真正麻烦的不是“怎么设编码”,而是CSV本身没标准:有BOM没BOM、字段含换行符、引号转义规则不一……编码只是第一道门。一旦开始处理真实业务里的CSV(比如用户上传、财务系统导出),很快会撞上分隔符冲突或空行解析异常——那时再回头调编码,已经晚了。











