encoding/csv.Reader.ReadAll în Go

Citește toate rândurile rămase dintr-un CSV deodată, ca [][]string; potrivit pentru fișiere mici.

Sintaxă
func (r *Reader) ReadAll() (records [][]string, err error)

Ce face encoding/csv.Reader.ReadAll

rd.ReadAll() apelează Read până la sfârșit și returnează toate rândurile într-un slice de slice-uri: rânduri[i][j] este coloana j din rândul i. La final nu returnează io.EOF, ci nil.

Tot fișierul ajunge în memorie, deci folosește-l pentru fișiere mici și medii (liste de clienți, tabele de prețuri). Pentru fișiere de sute de MB folosește Read într-o buclă.

Ce returnează

Toate rândurile ([][]string) și prima eroare de format, dacă există.

Exemple

Exemplul 1: Note citite dintr-un fișier

package main

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

func main() {
	os.WriteFile("note.csv", []byte("elev,mate,romana,info\nAna,9,10,10\nRadu,7,8,9\nIoana,10,9,10\n"), 0o644)

	f, err := os.Open("note.csv")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()

	randuri, err := csv.NewReader(f).ReadAll()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Rânduri citite:", len(randuri))
	for _, r := range randuri[1:] {
		suma := 0
		for _, n := range r[1:] {
			v, _ := strconv.Atoi(n)
			suma += v
		}
		fmt.Printf("%-6s media %.2f\n", r[0], float64(suma)/float64(len(r)-1))
	}
}

Rezultat

Rânduri citite: 4
Ana    media 9.67
Radu   media 8.00
Ioana  media 9.67

Exemplul 2: Rânduri transformate în map-uri după antet

package main

import (
	"encoding/csv"
	"fmt"
	"strings"
)

func main() {
	date := "cod,judet,resedinta\nIS,Iași,Iași\nCJ,Cluj,Cluj-Napoca\nBV,Brașov,Brașov\n"
	randuri, err := csv.NewReader(strings.NewReader(date)).ReadAll()
	if err != nil {
		fmt.Println(err)
		return
	}
	antet := randuri[0]
	for _, r := range randuri[1:] {
		m := map[string]string{}
		for i, col := range antet {
			m[col] = r[i]
		}
		fmt.Println(m)
	}
}

Rezultat

map[cod:IS judet:Iași resedinta:Iași]
map[cod:CJ judet:Cluj resedinta:Cluj-Napoca]
map[cod:BV judet:Brașov resedinta:Brașov]

Greșeli frecvente

  • Folosești ReadAll pe un fișier uriaș sau pe un corp de cerere fără limită: tot conținutul ajunge în memorie.
  • Accesezi randuri[1:] fără să verifici că fișierul nu e gol: dacă randuri are lungimea 0, programul se oprește cu panică.

Comenzi înrudite

  • encoding/csv.Reader: Citește fișiere CSV rând cu rând: NewReader creează cititorul, Read returnează următorul rând ca []string.
  • encoding/csv.Writer.WriteAll: Scrie toate rândurile date deodată și apelează singur Flush; returnează eroarea, dacă apare.