Working with CSV in Go (Golang): Parsing, Writing, and Data Processing
CSV (Comma-Separated Values) is one of the most common formats for exchanging tabular data. In Go (Golang), working with CSV is implemented natively through the standard package encoding/csv, making it a convenient and performant tool. In this article, we will thoroughly examine how to read, create, and process CSV files in Go, including working with large data volumes, configuring delimiters, and error handling.
The encoding/csv Package: Basics
The encoding/csv package provides two main types: Reader for reading CSV and Writer for writing. It supports standard CSV rules (RFC 4180) and allows flexible configuration of parameters such as delimiter, comments, and quote handling.
To get started, simply import the package:
import "encoding/csv"Reading a CSV File
Let's look at a simple example of reading a CSV file line by line:
package main
import ( "encoding/csv" "fmt" "os")
func main() { // Open the file file, err := os.Open("data.csv") if err != nil { panic(err) } defer file.Close()
// Create a Reader reader := csv.NewReader(file)
// Read all records records, err := reader.ReadAll() if err != nil { panic(err) }
// Output the data for i, record := range records { fmt.Printf("Row %d: %v", i, record) }}Important: ReadAll() loads the entire file into memory. For large files, use line-by-line reading with Read().
Line-by-Line Reading of Large CSV Files
For processing large data volumes (gigabytes), use iterative reading:
reader := csv.NewReader(file)for { record, err := reader.Read() if err != nil { // End of file if err.Error() == "EOF" { break } panic(err) } // Process the record fmt.Println(record)}Writing to a CSV File
Creating a CSV file is also intuitive:
package main
import ( "encoding/csv" "os")
func main() { file, err := os.Create("output.csv") if err != nil { panic(err) } defer file.Close()
writer := csv.NewWriter(file) defer writer.Flush() // Important: flush the buffer
// Write headers writer.Write([]string{"Name", "Age", "City"}) // Write data writer.Write([]string{"Alice", "30", "Moscow"}) writer.Write([]string{"Bob", "25", "Saint Petersburg"})}Don't forget to call Flush() after all write operations, otherwise data may be lost.
Configuring the Delimiter and Other Parameters
By default, a comma is used, but you can change the delimiter, for example, to a semicolon (TSV — tabulation):
reader := csv.NewReader(file)reader.Comma = ';' // For TSV: '\\t'
// For writing:writer := csv.NewWriter(file)writer.Comma = ';'Other useful parameters:
- LazyQuotes — allows quotes in non-standard places (default
false) - FieldsPerRecord — checks the number of fields (a negative value disables the check)
- Comment — comment character (e.g.,
'#'), lines starting with it are skipped - TrimLeadingSpace — automatic removal of leading spaces in fields
Example with settings:
reader := csv.NewReader(file)reader.Comma = '\\t'reader.Comment = '#'reader.TrimLeadingSpace = trueError Handling and Validation
CSV files often contain errors: extra quotes, mismatched field counts, etc. The encoding/csv package provides mechanisms for handling such situations. For example, setting FieldsPerRecord to a negative value disables the check for the number of fields, which can be useful for files with an inconsistent structure.
Also in library
Working with CSV in PHP: reading, writing, and data processing
ORM for C++: Comparison and Usage Examples (ODB, SOCI, SQLiteCpp)
Internationalization (i18n) in C++: A Complete Guide with gettext and ICU
Caching in Node.js: Redis, Memcached, and Node-Cache