File::sync_all în Rust

Forțează scrierea datelor și a metadatelor fișierului pe disc, nu doar în memoria tampon a sistemului.

Sintaxă
fn sync_all(&self) -> io::Result<()>

Ce face File::sync_all

Când scrii într-un fișier, sistemul de operare păstrează adesea datele un timp în memorie și le scrie pe disc mai târziu. Dacă se oprește curentul, ultimele date se pot pierde. sync_all() așteaptă până când datele și metadatele (dimensiune, dată) ajung efectiv pe disc.

Este important pentru date care nu au voie să se piardă: baze de date, jurnale de tranzacții, fișiere de configurare salvate. Este lent, deci nu-l apela după fiecare linie. Varianta sync_data() sincronizează doar conținutul. Dacă scrii printr-un BufWriter, fă întâi flush(), ca datele să ajungă în File.

Ce returnează

io::Result<()>.

Exemple

Exemplul 1: Salvare sigură a unei comenzi

use std::fs::File;
use std::io::Write;

fn main() -> std::io::Result<()> {
    let mut f = File::create("comanda_1042.txt")?;
    writeln!(f, "client: Ana Popescu")?;
    writeln!(f, "total: 249.90 lei")?;
    f.sync_all()?;
    println!("comanda a fost scrisă pe disc ({} octeți)", f.metadata()?.len());
    Ok(())
}

Rezultat

comanda a fost scrisă pe disc (38 octeți)

Exemplul 2: Împreună cu BufWriter

flush() trimite datele din BufWriter în fișier; get_ref() dă acces la File pentru sync_all.

use std::fs::File;
use std::io::{BufWriter, Write};

fn main() -> std::io::Result<()> {
    let mut w = BufWriter::new(File::create("jurnal.log")?);
    for i in 1..=3 {
        writeln!(w, "tranzacția {i} confirmată")?;
    }
    w.flush()?;
    w.get_ref().sync_all()?;
    print!("{}", std::fs::read_to_string("jurnal.log")?);
    Ok(())
}

Rezultat

tranzacția 1 confirmată
tranzacția 2 confirmată
tranzacția 3 confirmată

Greșeli frecvente

  • Apelezi sync_all pe File din spatele unui BufWriter fără flush(): datele din buffer nu au ajuns încă în fișier.
  • Apelezi sync_all după fiecare scriere mică: programul devine foarte lent.

Comenzi înrudite

  • File: Un fișier deschis: File::open îl deschide pentru citire, File::create îl creează (sau golește) pentru scriere.
  • io::BufWriter: Adaugă un buffer peste orice scriitor: strânge scrierile mici și le trimite în bucăți mari, mult mai rapid.
  • io::Write: Trait-ul oricărei destinații de octeți: write_all scrie tot bufferul, flush golește memoria tampon; permite write!.