在 Go (Golang) 中处理 CSV:encoding/csv 包完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Go 中的 encoding/csv 包:处理 CSV 文件的完整指南



CSV(逗号分隔值)格式仍然是交换表格数据最流行的方法之一。在 Go (Golang) 中,有一个标准包 encoding/csv 用于处理此格式,它提供了方便且高性能的接口来读取和写入 CSV 文件。在本文中,我们将详细介绍该包的所有功能,从基本操作到高级技术。



encoding/csv 包的主要功能

encoding/csv 包是 Go 标准库的一部分,无需安装额外的依赖项。它支持:

  • 使用可配置的分隔符读取 CSV 文件
  • 将数据写入 CSV 格式
  • 处理引号和转义特殊字符
  • 处理列标题
  • 惰性读取(大文件的流式处理)


在 Go 中读取 CSV 文件

要读取 CSV 文件,使用 csv.Reader 结构体。考虑一个基本示例:



package main

import ( "encoding/csv" "fmt" "log" "os")

func main() { // 打开 CSV 文件 file, err := os.Open("data.csv") if err != nil { log.Fatal("打开文件错误:", err) } defer file.Close()

// 创建一个新的 CSV reader reader := csv.NewReader(file)

// 一次性读取所有记录 records, err := reader.ReadAll() if err != nil { log.Fatal("读取 CSV 错误:", err) }

// 输出数据 for i, record := range records { fmt.Printf("行 %d: %v", i+1, record) }}


大文件的流式读取

为了处理大型 CSV 文件(数百兆字节或更多),建议逐行读取:



func readLargeCSV(filename string) error {    file, err := os.Open(filename)    if err != nil {        return err    }    defer file.Close()

reader := csv.NewReader(file) // 跳过标题行 header, err := reader.Read() if err != nil { return err } fmt.Println("标题:", header)

// 逐行读取 lineCount := 0 for { record, err := reader.Read() if err != nil { break // 文件结束 } // 处理记录 fmt.Printf("行 %d: %s | %s", lineCount+1, record[0], record[1]) lineCount++ } return nil}


配置 CSV 解析器

encoding/csv 包允许灵活配置读取参数:

  • Comma — 分隔符(默认为逗号)
  • Comment — 注释字符(以此字符开头的行将被忽略)
  • FieldsPerRecord — 每条记录中预期的字段数
  • LazyQuotes — 允许未转义的引号
  • TrimLeadingSpace — 删除字段开头的空格


func customCSVParser() {    file, _ := os.Open("custom.csv")    defer file.Close()

reader := csv.NewReader(file) reader.Comma = ';' // 使用分号 reader.Comment = '#' // 以 # 开头的行将被忽略 reader.TrimLeadingSpace = true reader.LazyQuotes = true

records, _ := reader.ReadAll() for _, record := range records { fmt.Println(record) }}


将数据写入 CSV 格式

要写入数据,使用 csv.Writer 结构体。创建 CSV 文件的示例:



func writeCSV(filename string) error {    file, err := os.Create(filename)    if err != nil {        return err    }    defer file.Close()

writer := csv.NewWriter(file) defer writer.Flush() // 重要!将缓冲区刷新到文件

// 写入标题

推荐