The encoding/csv Package in Go: A Complete Guide to Working with CSV Files
The CSV (Comma-Separated Values) format remains one of the most popular ways to exchange tabular data. In Go (Golang), the standard package encoding/csv provides a convenient and performant interface for reading and writing CSV files. In this article, we will thoroughly examine all the capabilities of the package, from basic operations to advanced techniques.
Key Features of the encoding/csv Package
The encoding/csv package is part of the Go standard library and does not require installing additional dependencies. It supports:
- Reading CSV files with customizable delimiters
- Writing data in CSV format
- Handling quotes and escaping special characters
- Working with column headers
- Lazy reading (streaming processing of large files)
Reading CSV Files in Go
To read a CSV file, the csv.Reader structure is used. Let's look at a basic example:
package main
import ( "encoding/csv" "fmt" "log" "os")
func main() { // Open the CSV file file, err := os.Open("data.csv") if err != nil { log.Fatal("Error opening file:", err) } defer file.Close()
// Create a new CSV reader reader := csv.NewReader(file)
// Read all records at once records, err := reader.ReadAll() if err != nil { log.Fatal("Error reading CSV:", err) }
// Print the data for i, record := range records { fmt.Printf("Row %d: %v", i+1, record) }}Streaming Reading of Large Files
For processing large CSV files (hundreds of megabytes or more), it is recommended to use line-by-line reading:
func readLargeCSV(filename string) error { file, err := os.Open(filename) if err != nil { return err } defer file.Close()
reader := csv.NewReader(file) // Skip the header header, err := reader.Read() if err != nil { return err } fmt.Println("Headers:", header)
// Read line by line lineCount := 0 for { record, err := reader.Read() if err != nil { break // End of file } // Process the record fmt.Printf("Row %d: %s | %s", lineCount+1, record[0], record[1]) lineCount++ } return nil}Configuring the CSV Parser
The encoding/csv package allows flexible configuration of reading parameters:
Comma— delimiter character (default is comma)Comment— comment character (lines starting with it are ignored)FieldsPerRecord— expected number of fields per recordLazyQuotes— allow unescaped quotesTrimLeadingSpace— trim leading spaces in fields
func customCSVParser() { file, _ := os.Open("custom.csv") defer file.Close()
reader := csv.NewReader(file) reader.Comma = ';' // Use semicolon reader.Comment = '#' // Lines starting with # are ignored reader.TrimLeadingSpace = true reader.LazyQuotes = true
records, _ := reader.ReadAll() for _, record := range records { fmt.Println(record) }}Writing Data in CSV Format
For writing, the csv.Writer structure is used. Example of creating a CSV file:
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() // Important! Flush the buffer to the file
// Write the header