bufio.NewReader în Go

Învelește un io.Reader într-un bufio.Reader, care citește pe blocuri și oferă ReadString, ReadRune, ReadLine.

Sintaxă
func NewReader(rd io.Reader) *Reader
func NewReaderSize(rd io.Reader, size int) *Reader

Ce face bufio.NewReader

bufio.NewReader creează un *bufio.Reader cu un buffer de 4096 octeți. În loc să ceară sistemului câte un octet, citește blocuri mari și îți dă datele din buffer. Pe lângă viteză, adaugă metode utile: ReadString, ReadBytes, ReadLine, ReadRune, Peek.

Tipul bufio.Reader este folosit des pentru citirea de la tastatură: bufio.NewReader(os.Stdin).ReadString('\n') citește un rând întreg, cu spații. Pentru citirea rând cu rând a unui fișier, bufio.Scanner este de obicei mai simplu.

Atenție: buffer-ul poate citi din sursă mai mult decât ai cerut tu. Nu mai citi direct din sursa originală după ce ai creat un bufio.Reader peste ea; folosește doar Reader-ul nou.

Parametri

Parametru Descriere
rd Sursa de citit (os.Stdin, un fișier, o conexiune).
size La NewReaderSize: dimensiunea buffer-ului.

Ce returnează

Un *bufio.Reader nou.

Exemple

Exemplul 1: Citirea numelui de la tastatură

ReadString('\n') păstrează și caracterul de rând nou; îl eliminăm cu strings.TrimSpace.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    cititor := bufio.NewReader(os.Stdin)
    fmt.Print("Cum te numești? ")
    nume, _ := cititor.ReadString('\n')
    nume = strings.TrimSpace(nume)
    fmt.Print("Din ce oraș ești? ")
    oras, _ := cititor.ReadString('\n')
    fmt.Printf("\nSalut, %s din %s!\n", nume, strings.TrimSpace(oras))
}

Ce scrie utilizatorul (intrare)

Ana Maria
Iași

Rezultat

Cum te numești? Din ce oraș ești? 
Salut, Ana Maria din Iași!

Exemplul 2: Peek: privire înainte fără consumare

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    r := bufio.NewReader(strings.NewReader("#comentariu\ndate utile"))
    inceput, _ := r.Peek(1)
    fmt.Printf("primul caracter: %q\n", inceput)

    rand, _ := r.ReadString('\n')
    fmt.Printf("primul rând: %q\n", rand)
    fmt.Println("în buffer:", r.Buffered(), "octeți")
}

Rezultat

primul caracter: "#"
primul rând: "#comentariu\n"
în buffer: 10 octeți

Greșeli frecvente

  • Creezi un bufio.NewReader(os.Stdin) nou pentru fiecare întrebare. Primul Reader poate fi citit deja în buffer și rândurile următoare; creează unul singur și refolosește-l.
  • Amesteci fmt.Scan cu un bufio.Reader pe același os.Stdin. Datele din buffer-ul unuia nu le vede celălalt.

Comenzi înrudite

  • bufio.Reader.ReadString: Citește până la (și inclusiv) caracterul delimitator; ReadString dă un string, ReadBytes un []byte.
  • bufio.Reader.ReadRune: Citește un singur caracter Unicode (rune), decodând corect literele de mai mulți octeți ca ă, ș, €.
  • bufio.Reader.ReadLine: Citește un rând fără caracterul de final, la nivel scăzut; rândurile prea lungi vin pe bucăți.
  • bufio.NewScanner: Creează un bufio.Scanner, cel mai simplu mod de a citi un text rând cu rând (sau cuvânt cu cuvânt).
  • io.Reader: Interfața pentru orice sursă de date din care se poate citi: fișiere, text, conexiuni, răspunsuri HTTP.