io::BufRead în Rust

Trait-ul cititorilor cu buffer: oferă citire pe linii (lines, read_line) pentru fișiere, stdin și octeți din memorie.

Sintaxă
use std::io::BufRead;

fn lines(self) -> Lines<Self>
fn read_line(&mut self, buf: &mut String) -> io::Result<usize>

Ce face io::BufRead

BufRead este implementat de cititorii care au o zonă tampon: BufReader<File>, StdinLock, &[u8], io::Cursor. Datorită buffer-ului, pot găsi eficient sfârșitul unei linii.

lines() dă un iterator de io::Result<String>, fără caracterele de linie nouă. read_line(&mut s) adaugă următoarea linie (cu \n) la s și returnează câți octeți a citit, 0 la final. Ca să folosești metodele, trait-ul trebuie importat: use std::io::BufRead;.

Parametri

Parametru Descriere
buf La read_line: textul la care se adaugă linia.

Ce returnează

lines: iterator de io::Result<String>. read_line: io::Result<usize>.

Exemple

Exemplul 1: Citirea unui fișier linie cu linie

Fișierul nu este încărcat tot în memorie: se citește câte o bucată, iar lines() desparte liniile.

use std::fs::{self, File};
use std::io::{self, BufRead, BufReader};

fn main() -> io::Result<()> {
    fs::write("orase.csv", "oras,populatie\nIași,271692\nCluj-Napoca,286598\nBrașov,237589\n")?;

    let cititor = BufReader::new(File::open("orase.csv")?);
    for (nr, linie) in cititor.lines().enumerate().skip(1) {
        let linie = linie?;
        if let Some((oras, pop)) = linie.split_once(',') {
            println!("{nr}. {oras}: {pop} locuitori");
        }
    }
    Ok(())
}

Rezultat

1. Iași: 271692 locuitori
2. Cluj-Napoca: 286598 locuitori
3. Brașov: 237589 locuitori

Exemplul 2: read_line pe octeți din memorie

Un &[u8] implementează și el BufRead, util pentru teste. read_line păstrează \n, deci afișăm cu {:?}.

use std::io::{self, BufRead};

fn main() -> io::Result<()> {
    let mut date: &[u8] = b"prima linie\na doua\nultima fara enter";
    let mut linie = String::new();
    loop {
        linie.clear();
        let n = date.read_line(&mut linie)?;
        if n == 0 {
            break;
        }
        println!("{n:2} octeți: {linie:?}");
    }
    Ok(())
}

Rezultat

12 octeți: "prima linie\n"
 7 octeți: "a doua\n"
17 octeți: "ultima fara enter"

Greșeli frecvente

  • Uiți use std::io::BufRead;: eroarea no method named `lines` found for struct `BufReader`.
  • Apelezi lines() direct pe File: File nu are buffer, deci nu implementează BufRead. Împachetează-l în BufReader::new.

Comenzi înrudite

  • io::BufReader: Adaugă un buffer peste orice cititor (de obicei un File): citiri mai rapide și acces la metodele BufRead.
  • io::Stdin::lines: Parcurge intrarea standard linie cu linie, ca iterator de String-uri fără caracterul de linie nouă.
  • io::Read: Trait-ul oricărei surse de octeți (fișier, stdin, rețea): read_to_string și read_to_end citesc tot ce a rămas.
  • fs::read_to_string: Citește tot conținutul unui fișier text într-un String, dintr-un singur apel.