strings.Reader în Go

Face dintr-un text o sursă de citire (io.Reader), ca să-l dai funcțiilor care citesc din fișiere sau rețea.

Sintaxă
func NewReader(s string) *Reader
func (r *Reader) Len() int
func (r *Reader) Read(b []byte) (n int, err error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) Seek(offset int64, whence int) (int64, error)

Ce face strings.Reader

Multe funcții din Go citesc dintr-un io.Reader: bufio.Scanner, fmt.Fscan, json.NewDecoder, http.NewRequest. strings.NewReader(s) transformă un text într-o astfel de sursă, fără să copieze textul. Este foarte util în teste și exemple, unde nu vrei să creezi un fișier.

*strings.Reader are metode de citire: Read (octeți), ReadByte, ReadRune (un caracter întreg), ReadAt, Seek (mutarea poziției), WriteTo. Len() spune câți octeți au rămas necitiți, iar Size() lungimea totală.

Pentru a scrie un text pas cu pas, folosește strings.Builder; Reader este doar pentru citire.

Parametri

Parametru Descriere
s La NewReader: textul din care se va citi.

Ce returnează

NewReader returnează un *strings.Reader, care implementează io.Reader, io.RuneReader, io.Seeker și altele.

Exemple

Exemplul 1: Citire rând cu rând cu bufio.Scanner

package main

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

func main() {
	date := "Ana,10\nIon,8\nMaria,9\n"
	sc := bufio.NewScanner(strings.NewReader(date))
	for sc.Scan() {
		nume, nota, _ := strings.Cut(sc.Text(), ",")
		fmt.Printf("%s are nota %s\n", nume, nota)
	}
}

Rezultat

Ana are nota 10
Ion are nota 8
Maria are nota 9

Exemplul 2: Citire caracter cu caracter și poziția rămasă

ReadRune spune și câți octeți a ocupat caracterul: ș și ț ocupă 2.

package main

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

func main() {
	r := strings.NewReader("Țară")
	fmt.Println("total:", r.Size(), "octeți")
	for {
		ch, marime, err := r.ReadRune()
		if err == io.EOF {
			break
		}
		fmt.Printf("%c ocupă %d octet(i), rămân %d\n", ch, marime, r.Len())
	}
	r.Seek(0, io.SeekStart)
	tot, _ := io.ReadAll(r)
	fmt.Println("recitit:", string(tot))
}

Rezultat

total: 6 octeți
Ț ocupă 2 octet(i), rămân 4
a ocupă 1 octet(i), rămân 3
r ocupă 1 octet(i), rămân 2
ă ocupă 2 octet(i), rămân 0
recitit: Țară

Greșeli frecvente

  • Citești până la capăt și apoi încerci să citești din nou: primești io.EOF. Întoarce-te la început cu r.Seek(0, io.SeekStart) sau creează alt Reader.
  • Folosești r.Len() ca lungime totală. După citire, Len scade; lungimea totală este Size().

Comenzi înrudite

  • strings.Builder: Construiește eficient un text din multe bucăți: adaugi cu WriteString, WriteByte, WriteRune sau Write și obții rezultatul cu String().
  • fmt.Fscan: Citește valori dintr-un io.Reader (fișier, buffer, os.Stdin) în variabile, ca Scan, Scanf și Scanln.
  • bytes.Buffer.Read: Citește din buffer octeți (Read, ReadByte) sau caractere (ReadRune); UnreadByte și UnreadRune pun înapoi ultima citire.