Working with CSV in Go (Golang): A Complete Guide
CSV (Comma-Separated Values) is one of the most common formats for exchanging tabular data. In the Go (Golang) language, working with CSV is organized through the standard package encoding/csv. It provides a convenient and high-performance interface for reading and writing CSV files, supports delimiter configuration, character escaping, and error handling.
In this article, we will thoroughly examine all the capabilities of the encoding/csv package with practical examples. You will learn how to read CSV files line by line and entirely, write data, configure parsing parameters, and handle typical errors.
Installation and Import
The encoding/csv package is part of the Go standard library, so no additional installation is required. To use it, simply import it into your code:
import ( "encoding/csv" "fmt" "os")Reading CSV Files
The simplest way to read a CSV is to use csv.NewReader and the ReadAll method, which returns all records as a slice of slices of strings.
func readAllExample(filename string) { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close()
reader := csv.NewReader(file) records, err := reader.ReadAll() if err != nil { panic(err) }
for _, record := range records { fmt.Println(record) }}For large files, it is better to use line-by-line reading via the Read method to avoid loading the entire file into memory:
func readLineByLine(filename string) { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close()
reader := csv.NewReader(file) reader.LazyQuotes = true // allows lenient quote parsing
for { record, err := reader.Read() if err != nil { break // end of file or error } fmt.Println(record) }}Writing CSV Files
To write data, use csv.NewWriter. The Write method writes one record, and WriteAll writes all at once. Don't forget to call Flush() to flush the buffer.
func writeExample(filename string) { file, err := os.Create(filename) if err != nil { panic(err) } defer file.Close()
writer := csv.NewWriter(file) defer writer.Flush()
data := [][]string{ {"Name", "Age", "City"}, {"Anna", "28", "Moscow"}, {"Ivan", "35", "Saint Petersburg"}, }
for _, record := range data { if err := writer.Write(record); err != nil { panic(err) } }}Configuring Delimiter and Escaping
By default, encoding/csv uses a comma as the delimiter and double quotes for escaping. You can change these settings through the fields of the Reader and Writer structs:
func customSettings() { // Reading TSV (Tab-Separated Values) file, _ := os.Open("data.tsv") defer file.Close()
reader := csv.NewReader(file) reader.Comma = '\\t' // tab instead of comma reader.Comment = '#' // ignore lines starting with #
records, _ := reader.ReadAll() fmt.Println(records)}Useful fields for configuration:
Comma— delimiter character (default ',')Comment— comment character (lines starting with this character are ignored)LazyQuotes— allows lenient quote parsingTrimLeadingSpace— removes leading spaces from fieldsFieldsPerRecord— expected number