Golang如何写入CSV文件_Golang CSV文件读写实现方法

7次阅读

最稳妥方式是用 encoding/csv 的 csv.Writer 配合 *os.File,需确保文件以 os.O_CREATE|os.O_WRONLY|os.O_TRUNC 模式打开、每行调用 wr.Write([]String{…})、写完必须 wr.Flush() 和 file.Close(),并按需在文件开头写入 UTF-8 bom(xEFxBBxBF)以兼容 windows 记事本。

Golang如何写入CSV文件_Golang CSV文件读写实现方法

encoding/csv 写入 CSV 文件最稳妥

go 标准库的 encoding/csv 是写入 CSV 的首选,它自动处理字段中的逗号、换行符和双引号转义,避免手动拼接出错。直接用 csv.Writer 配合 *os.File 即可,不需要第三方包。

常见错误是忘记调用 wr.Flush()file.Close(),导致最后一行数据没写入磁盘;还有人误用 fmt.Fprintln 直接写字符串,结果字段含换行时 CSV 结构被破坏。

  • 写入前确保文件以 os.O_CREATE | os.O_WRONLY | os.O_TRUNC 模式打开
  • 每行用 wr.Write([]string{...}),不是 WriteString
  • 写完必须调用 wr.Flush(),否则缓冲区内容可能丢失
  • 结构体转 CSV 需手动提取字段,标准库不支持 tag 自动映射(如 csv:"name"

写入含中文或特殊字符的 CSV 要注意 BOM

windows 记事本默认用 GBK 或 UTF-8 with BOM 识别中文,纯 UTF-8(无 BOM)可能显示乱码。Go 默认写的是无 BOM 的 UTF-8,所以 excel 打开中文字段常变问号。

解决方法是在文件开头写入 UTF-8 BOM(uFEFF),但不能直接写进 csv.Writer——得先写 BOM 到底层 *os.File,再把 csv.Writer 绑定到该文件。

立即学习go语言免费学习笔记(深入)”;

  • 打开文件后立即调用 file.Write([]byte("xEFxBBxBF"))
  • 再用 csv.NewWriter(file),后续写入保持正常
  • 不要对 BOM 做任何编码转换,它是字节序列,不是字符串
  • 如果目标是跨平台程序(比如导出给 mac/linux 用户),BOM 反而可能引发解析异常,需按使用方要求决定是否添加

csv.Writewrite Error: bad file descriptor 怎么办

这个错误通常不是权限问题,而是文件对象已被关闭,或者 Writer 绑定在已关闭的文件上。典型场景是:函数内打开文件 → 创建 Writer → defer 关闭文件 → 然后调用 Write → 最后 defer 触发关闭 → 下次 Write 就崩了。

  • 确保 file.Close() 在所有 wr.Write()wr.Flush() 之后执行
  • 不要在循环中反复创建 csv.Writer,它本身带缓冲,复用更高效
  • 如果用 defer file.Close(),把它放在 wr.Flush() 之后,或改用显式 close
  • 检查是否对同一文件句柄并发写入(比如多个 goroutine 共用一个 *csv.Writer),这会触发竞态且大概率报错

性能敏感场景下如何批量写入 CSV

单次 wr.Write() 写一行没问题,但循环写几千行时,频繁系统调用会影响速度。标准库的 csv.Writer 已内置缓冲(默认 4KB),但可以主动加大提升吞吐。

  • bufio.NewWriterSize(file, 64*1024) 包一层,再传给 csv.NewWriter
  • 避免在循环里做字段拼接或类型转换,提前准备好 []string
  • 如果数据来自数据库查询,别用 rows.Scan() 逐字段读,改用 rows.Columns() + rows.Next() + rows.Values() 一次性取整行 []Interface{},再统一转 string
  • 内存充足时,可先写入 bytes.Buffer,最后一次性 WriteTo 到文件,减少 I/O 次数

CSV 写入真正的复杂点不在语法,而在边界场景:BOM 兼容性、大文件 flush 时机、多语言字段的编码一致性。这些地方一漏,下游用 Excel 或 python pandas 打开就立刻暴露。

text=ZqhQzanResources