csv.Reader需手动调用Read()或ReadAll(),不自动解析;含BOM需手动去除;csv.Writer写入需显式写header并Flush;编码非UTF-8须预转换;错误须用*csv.ParseError断言捕获。

csv.Reader 读取时必须手动调用 Read() 或 ReadAll(),不自动解析整文件
Go 的 csv.Reader 是流式读取器,初始化后不会自动加载数据。常见错误是只创建了 csv.NewReader() 就直接去取字段,结果返回空切片或 panic。
- 用
Read()逐行读:每次返回一个[]string,遇到 EOF 返回io.EOF - 用
ReadAll()一次性读完:适合小文件,大文件可能 OOM;返回[][]string - 如果 CSV 含 BOM(如 Windows 记事本保存的 UTF-8),需先用
bytes.TrimPrefix(buf, []byte{0xEF, 0xBB, 0xBF})去掉
写入 CSV 时 Write() 不自动换行,WriteAll() 也不加表头
csv.Writer 的 Write() 只写一行数据,不附加换行符;WriteAll() 写多行,但也不会在开头加 header 行——header 必须显式调用一次 Write()。
- 写 header:
w.Write([]string{"name", "age", "city"}) - 写数据行:
w.Write([]string{"Alice", "28", "Beijing"}) - 别忘了最后调用
w.Flush(),否则缓冲区内容可能丢失 - 若某字段含换行符、逗号或双引号,
csv.Writer会自动加引号和转义,无需手动处理
中文乱码常见于文件编码非 UTF-8,而 Go 默认按 UTF-8 解析
Go 标准库的 encoding/csv 完全不处理字符编码转换。如果文件是 GBK、GB2312 或 UTF-16 编码,直接读会显示乱码甚至解析失败(如 invalid UTF-8 错误)。
- 确认源文件编码:可用
file命令或 VS Code 底部状态栏查看 - GBK 转 UTF-8:导入
golang.org/x/text/encoding/simplifiedchinese,用gbk.NewDecoder().Bytes(data)预处理字节流 - 不要尝试用
strings.ToValidUTF8()损坏性修复,会导致数据失真
csv.Read() 遇到格式错误默认 panic,要用 csv.ParseError 类型断言捕获
当某行字段数不一致、引号不匹配或转义错误时,Read() 返回的 error 是 *csv.ParseError,包含 Line、Column 和 Err 字段,方便定位问题。
立即学习“go语言免费学习笔记(深入)”;
- 正确捕获:
if err != nil { if pe, ok := err.(*csv.ParseError); ok { log.Printf("parse error at line %d, column %d: %v", pe.Line, pe.Column, pe.Err) } } - 跳过错误行?可以,但需手动调用
reader.Input()获取剩余未解析字节并重置 reader(较复杂),更稳妥的做法是预校验或改用带容错的第三方库(如github.com/mithrandie/csvq) - 注意:
ReadAll()遇错直接返回全部已读数据 + error,不会丢弃前面的行










