os.File.Close în Go

Închide fișierul și eliberează resursele sistemului; după Close fișierul nu mai poate fi folosit.

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

Ce face os.File.Close

Close închide fișierul. Fiecare program are un număr limitat de fișiere deschise simultan; dacă nu le închizi, la un moment dat os.Open eșuează cu „too many open files”.

Pentru fișierele în care ai scris, Close poate returna o eroare importantă (de exemplu discul plin, pe unele sisteme de fișiere eroarea apare abia la închidere). Pentru citire poți folosi liniștit defer f.Close(); pentru scriere, verifică și eroarea lui Close.

Un al doilea Close pe același fișier returnează eroarea os.ErrClosed.

Ce returnează

nil sau eroarea apărută la închidere.

Exemple

Exemplul 1: Închidere cu defer la citire

package main

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

func numaraRanduri(nume string) (int, error) {
    f, err := os.Open(nume)
    if err != nil {
        return 0, err
    }
    defer f.Close() // rulează când funcția se termină

    n := 0
    s := bufio.NewScanner(f)
    for s.Scan() {
        n++
    }
    return n, s.Err()
}

func main() {
    os.WriteFile("orase.txt", []byte("Iași\nCluj\nBrașov\n"), 0o644)
    fmt.Println(numaraRanduri("orase.txt"))
}

Rezultat

3 <nil>

Exemplul 2: Eroarea lui Close la scriere

Returnăm eroarea lui Close dacă scrierea a reușit, ca să nu pierdem o problemă de salvare.

package main

import (
    "fmt"
    "os"
)

func salveaza(nume, text string) (err error) {
    f, err := os.Create(nume)
    if err != nil {
        return err
    }
    defer func() {
        if errClose := f.Close(); err == nil {
            err = errClose
        }
    }()
    _, err = f.WriteString(text)
    return err
}

func main() {
    fmt.Println(salveaza("raport.txt", "vânzări: 1200 lei\n"))
}

Rezultat

<nil>

Exemplul 3: Folosirea după închidere

package main

import (
    "fmt"
    "os"
)

func main() {
    f, _ := os.Create("nota.txt")
    fmt.Println("primul Close:", f.Close())
    fmt.Println("al doilea Close:", f.Close())

    _, err := f.WriteString("prea târziu")
    fmt.Println("scriere:", err)
}

Rezultat

primul Close: <nil>
al doilea Close: close nota.txt: file already closed
scriere: write nota.txt: file already closed

Greșeli frecvente

  • Uiți să închizi fișierele într-un server care rulează zile întregi. Fișierele deschise se adună până la eroarea „too many open files”.
  • Ignori eroarea lui Close după scriere. Datele pot să nu fi fost salvate și nu afli niciodată.

Comenzi înrudite

  • os.File: Tipul care reprezintă un fișier deschis; îl obții cu os.Open, os.Create sau os.OpenFile.
  • os.File.Sync: Forțează scrierea pe disc a datelor din fișier, ca să nu se piardă la o pană de curent.
  • io.Closer: Interfața pentru orice resursă care trebuie închisă după folosire (fișiere, conexiuni, corpuri HTTP).
  • os.File.Write: Scrie octeți (Write) sau text (WriteString) în fișier, la poziția curentă.