bufio.Reader.ReadLine în Go

Citește un rând fără caracterul de final, la nivel scăzut; rândurile prea lungi vin pe bucăți.

Sintaxă
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)

Ce face bufio.Reader.ReadLine

ReadLine returnează un rând fără \n sau \r\n. Dacă rândul nu încape în buffer, primești o bucată și isPrefix = true; restul vine la apelurile următoare.

Documentația o descrie ca primitivă de nivel scăzut: majoritatea programelor ar trebui să folosească ReadString('\n'), ReadBytes('\n') sau bufio.Scanner. Slice-ul returnat arată în buffer-ul intern și este valabil doar până la următoarea citire.

Ce returnează

Rândul (sau o bucată din el), isPrefix și eroarea (io.EOF la final).

Exemple

Exemplul 1: Rânduri fără caracterul de final

Și \r\n (format Windows) este eliminat.

package main

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

func main() {
    r := bufio.NewReader(strings.NewReader("Ana\r\nMihai\nIoana"))
    for {
        linie, _, err := r.ReadLine()
        if err != nil {
            fmt.Println("stop:", err)
            break
        }
        fmt.Printf("%q\n", linie)
    }
}

Rezultat

"Ana"
"Mihai"
"Ioana"
stop: EOF

Exemplul 2: Rând mai lung decât buffer-ul

Cu un buffer de 16 octeți (minimul permis), rândul lung vine în bucăți marcate cu isPrefix.

package main

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

func main() {
    text := "Acesta este un rând foarte lung din jurnal\nscurt\n"
    r := bufio.NewReaderSize(strings.NewReader(text), 16)
    var complet []byte
    for {
        bucata, prefix, err := r.ReadLine()
        if err != nil {
            break
        }
        complet = append(complet, bucata...)
        fmt.Printf("bucată %q, continuă: %v\n", bucata, prefix)
        if !prefix {
            fmt.Printf("=> rând complet: %q\n", complet)
            complet = complet[:0]
        }
    }
}

Rezultat

bucată "Acesta este un r", continuă: true
bucată "ând foarte lung", continuă: true
bucată " din jurnal", continuă: false
=> rând complet: "Acesta este un rând foarte lung din jurnal"
bucată "scurt", continuă: false
=> rând complet: "scurt"

Greșeli frecvente

  • Păstrezi slice-ul primit și citești mai departe. Datele din el sunt suprascrise; copiază-le (append([]byte(nil), linie...)).
  • Ignori isPrefix și tratezi bucățile ca rânduri separate.

Comenzi înrudite

  • bufio.Reader.ReadString: Citește până la (și inclusiv) caracterul delimitator; ReadString dă un string, ReadBytes un []byte.
  • 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.NewReader: Învelește un io.Reader într-un bufio.Reader, care citește pe blocuri și oferă ReadString, ReadRune, ReadLine.