🗒️ Read a CSV file in Go

introduction file csv

To easily read and parse CSV (or TSV) files in Go, you can use two methods of encoding/csv package:

See also our example of how to write data to a CSV file in Go

In the examples below, we use data.csv file:

vegetables,fruits
carrot,banana
potato,strawberry

Read the entire CSV file at once

In this example, we open the CSV file, initialize csv.Reader and read all the data into a [][]string slice where the first index is the file’s line number and the second is an index of the comma-separated value in this line. We can do something with these data, for example, convert to an array of structs.

package main

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

type ShoppingRecord struct {
    Vegetable string
    Fruit     string
}

func createShoppingList(data [][]string) []ShoppingRecord {
    var shoppingList []ShoppingRecord
    for i, line := range data {
        if i > 0 { // omit header line
            var rec ShoppingRecord
            for j, field := range line {
                if j == 0 {
                    rec.Vegetable = field
                } else if j == 1 {
                    rec.Fruit = field
                }
            }
            shoppingList = append(shoppingList, rec)
        }
    }
    return shoppingList
}

func main() {
    // open file
    f, err := os.Open("data.csv")
    if err != nil {
        log.Fatal(err)
    }

    // remember to close the file at the end of the program
    defer f.Close()

    // read csv values using csv.Reader
    csvReader := csv.NewReader(f)
    data, err := csvReader.ReadAll()
    if err != nil {
        log.Fatal(err)
    }

    // convert records to array of structs
    shoppingList := createShoppingList(data)

    // print the array
    fmt.Printf("%+v\n", shoppingList)
}

Output:

[{Vegetable:carrot Fruit:banana} {Vegetable:potato Fruit:strawberry}]

Read a CSV file line by line

Reading line by line is similar to reading the whole file at once, but in this case, we use csv.Reader.Read() method to read the next line of data in the infinite loop. This loop is exited when no more data are available, i.e., io.EOF error occurs.

package main

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

func main() {
    // open file
    f, err := os.Open("data.csv")
    if err != nil {
        log.Fatal(err)
    }

    // remember to close the file at the end of the program
    defer f.Close()

    // read csv values using csv.Reader
    csvReader := csv.NewReader(f)
    for {
        rec, err := csvReader.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        // do something with read line
        fmt.Printf("%+v\n", rec)
    }
}

Output:

[vegetables fruits]
[carrot banana]
[potato strawberry]

Use a non-default field delimiter and read a TSV file

The standard separator for csv.Reader is the comma, but it’s easy to change it to any rune. For instance, you can change it to the tab character \t, and in this way, you get the TSV reader:

csvReader.Comma = '\t'

📎 Convert JSON to CSV in Go

Learn how to transform JSON file to CSV
introduction file json csv

🔄 Convert CSV to JSON in Go

Learn how to transform CSV file data to JSON
introduction file csv json

✒️ Write to a CSV file in Go

Learn how to write data to a CSV or TSV file
introduction file csv