os.File.Sync în Go

Forțează scrierea pe disc a datelor din fișier, ca să nu se piardă la o pană de curent.

Sintaxă
func (f *File) Sync() error

Ce face os.File.Sync

Când apelezi Write, sistemul de operare păstrează adesea datele în memorie și le scrie pe disc mai târziu. Dacă se oprește curentul sau sistemul se blochează, aceste date se pot pierde. Sync (apelul fsync) așteaptă până când datele ajung efectiv pe disc.

Sync este lent, așa că îl folosești doar unde contează: baze de date, fișiere de configurare salvate, jurnale de tranzacții. Pentru programele obișnuite nu este necesar. Sync nu golește un bufio.Writer: apelează întâi Flush.

Ce returnează

nil dacă datele sunt pe disc, altfel eroarea.

Exemple

Exemplul 1: Salvare sigură a unei comenzi

package main

import (
    "fmt"
    "os"
)

func salveazaComanda(text string) error {
    f, err := os.OpenFile("comenzi.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
    if err != nil {
        return err
    }
    defer f.Close()
    if _, err := f.WriteString(text + "\n"); err != nil {
        return err
    }
    return f.Sync() // abia acum comanda este sigur pe disc
}

func main() {
    fmt.Println(salveazaComanda("1042;Ana Popescu;249.90"))
    date, _ := os.ReadFile("comenzi.log")
    fmt.Print(string(date))
}

Rezultat

<nil>
1042;Ana Popescu;249.90

Exemplul 2: Ordinea corectă cu bufio

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Create("export.csv")
    defer f.Close()
    w := bufio.NewWriter(f)
    for i := 1; i <= 3; i++ {
        fmt.Fprintf(w, "%d;produs %d\n", i, i)
    }
    fmt.Println("Flush:", w.Flush()) // din buffer în fișier
    fmt.Println("Sync:", f.Sync())   // din memoria sistemului pe disc

    date, _ := os.ReadFile("export.csv")
    fmt.Print(string(date))
}

Rezultat

Flush: <nil>
Sync: <nil>
1;produs 1
2;produs 2
3;produs 3

Greșeli frecvente

  • Apelezi Sync după fiecare rând într-o buclă mare. Programul devine foarte lent; sincronizează o dată, la final, sau la intervale.
  • Crezi că Sync golește și bufio.Writer. Nu; Flush trebuie apelat înainte.

Comenzi înrudite

  • os.File.Close: Închide fișierul și eliberează resursele sistemului; după Close fișierul nu mai poate fi folosit.
  • bufio.Writer.Flush: Trimite la destinație toate datele rămase în buffer-ul unui bufio.Writer.
  • os.File.Write: Scrie octeți (Write) sau text (WriteString) în fișier, la poziția curentă.