bufio.Scanner.Text în Go

Text returnează bucata curentă găsită de Scan, ca string; Bytes o returnează ca []byte, fără copiere.

Sintaxă
func (s *Scanner) Text() string
func (s *Scanner) Bytes() []byte

Ce face bufio.Scanner.Text

După un Scan reușit, Text returnează bucata găsită, ca un string nou. Pentru rânduri, textul nu conține \n sau \r\n.

Bytes returnează aceeași bucată ca []byte, dar fără copiere: slice-ul arată în buffer-ul intern și este suprascris de următorul Scan. E mai rapid când doar inspectezi datele; dacă vrei să le păstrezi, copiază-le sau folosește Text.

Ce returnează

Bucata curentă, ca string (Text) sau ca []byte (Bytes).

Exemple

Exemplul 1: Text pentru prelucrarea rândurilor

package main

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

func main() {
    csv := "Ana,Iași,9\nMihai,Cluj,7\n"
    s := bufio.NewScanner(strings.NewReader(csv))
    for s.Scan() {
        campuri := strings.Split(s.Text(), ",")
        fmt.Printf("%s din %s are nota %s\n", campuri[0], campuri[1], campuri[2])
    }
}

Rezultat

Ana din Iași are nota 9
Mihai din Cluj are nota 7

Exemplul 2: Bytes fără copiere și capcana păstrării

Prima buclă doar verifică fiecare rând, deci Bytes e potrivit. În a doua, slice-urile salvate cu Bytes arată în buffer-ul intern, care e rescris pe măsură ce se citește: primul rând salvat ajunge stricat. Cu Text, fiecare rând e o copie separată. Folosim un buffer mic ca efectul să apară pe un text scurt; pe fișiere mari se întâmplă la fel.

package main

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

func main() {
    text := "eroare: disc plin\ninfo: pornit\neroare: timeout\n"

    s := bufio.NewScanner(strings.NewReader(text))
    erori := 0
    for s.Scan() {
        if bytes.HasPrefix(s.Bytes(), []byte("eroare")) { // fără copiere
            erori++
        }
    }
    fmt.Println("erori:", erori)

    s = bufio.NewScanner(strings.NewReader(text))
    s.Buffer(make([]byte, 0, 32), 32) // buffer mic, ca efectul să se vadă pe un text scurt
    var gresit [][]byte
    var corect []string
    for s.Scan() {
        gresit = append(gresit, s.Bytes())
        corect = append(corect, s.Text())
    }
    fmt.Printf("păstrate cu Bytes: %q\n", gresit)
    fmt.Printf("păstrate cu Text:  %q\n", corect)
}

Rezultat

erori: 2
păstrate cu Bytes: ["eroare: timeout\nn" "info: pornit" "eroare: timeout"]
păstrate cu Text:  ["eroare: disc plin" "info: pornit" "eroare: timeout"]

Greșeli frecvente

  • Păstrezi rezultatul lui Bytes() într-o listă. Datele se schimbă la următorul Scan; folosește Text() sau copiază cu bytes.Clone.

Comenzi înrudite

  • bufio.Scanner.Scan: Trece la următoarea bucată (rând, cuvânt) din sursă; returnează false când nu mai sunt date sau a apărut o eroare.
  • 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).
  • bufio.Scanner.Split: Alege cum împarte Scanner-ul datele: pe rânduri (implicit), cuvinte, caractere, octeți sau după o regulă proprie.