Working with CSV in Go (Golang): A Complete Guide to the encoding/csv Package

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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 record
  • LazyQuotes — allow unescaped quotes
  • TrimLeadingSpace — 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

Recommendations