io.ReadAll în Go

Citește tot ce oferă un Reader, până la final, și returnează datele ca slice de octeți.

Sintaxă
func ReadAll(r Reader) ([]byte, error)

Ce face io.ReadAll

io.ReadAll apelează Read până la io.EOF și adună totul într-un []byte. Sfârșitul normal (io.EOF) nu este raportat ca eroare. Înainte de Go 1.16 funcția se numea ioutil.ReadAll.

Este comodă pentru surse mici: corpul unui răspuns HTTP, un fișier mic deja deschis, ieșirea unei comenzi. Pentru surse mari sau nesigure, limitează dimensiunea cu io.LimitReader sau prelucrează pe bucăți.

Parametri

Parametru Descriere
r Sursa de citit.

Ce returnează

Toți octeții citiți și nil, sau datele citite până la eroare și eroarea.

Exemple

Exemplul 1: Citirea dintr-un Reader

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Primul rând\nAl doilea rând\n")
    date, err := io.ReadAll(r)
    fmt.Printf("%d octeți, eroare: %v\n", len(date), err)
    fmt.Print(string(date))
}

Rezultat

29 octeți, eroare: <nil>
Primul rând
Al doilea rând

Exemplul 2: Limită de siguranță

Citim cel mult 10 octeți plus unul; dacă am primit mai mult de 10, sursa este prea mare.

package main

import (
    "errors"
    "fmt"
    "io"
    "strings"
)

func citesteMax(r io.Reader, max int64) (string, error) {
    date, err := io.ReadAll(io.LimitReader(r, max+1))
    if err != nil {
        return "", err
    }
    if int64(len(date)) > max {
        return "", errors.New("date prea mari")
    }
    return string(date), nil
}

func main() {
    text, err := citesteMax(strings.NewReader("salut"), 10)
    fmt.Printf("%q %v\n", text, err)
    text, err = citesteMax(strings.NewReader("un text mult prea lung"), 10)
    fmt.Printf("%q %v\n", text, err)
}

Rezultat

"salut" <nil>
"" date prea mari

Greșeli frecvente

  • Folosești io.ReadAll pe date venite de la utilizatori (încărcări, cereri HTTP) fără limită. Cineva poate trimite GB de date și programul rămâne fără memorie.

Comenzi înrudite

  • io.ReadFull: ReadFull umple complet buffer-ul din Reader; ReadAtLeast citește cel puțin min octeți.
  • io.Copy: Copiază toate datele dintr-un Reader într-un Writer, pe bucăți, fără să le țină pe toate în memorie.
  • os.ReadFile: Citește tot conținutul unui fișier într-un slice de octeți, dintr-un singur apel.
  • io.Reader: Interfața pentru orice sursă de date din care se poate citi: fișiere, text, conexiuni, răspunsuri HTTP.