os.CreateTemp în Go

Creează și deschide un fișier temporar nou, cu nume unic, și îl returnează ca *os.File.

Sintaxă
func CreateTemp(dir, pattern string) (*File, error)

Ce face os.CreateTemp

os.CreateTemp creează un fișier cu un nume care nu se repetă și îl deschide pentru citire și scriere (drepturi 0o600, doar pentru proprietar). Partea aleatorie înlocuiește ultima * din pattern sau, dacă nu există, se adaugă la final: "export-*.csv" dă de exemplu export-2846123907.csv.

Cu dir gol, fișierul se creează în os.TempDir(). Afli numele cu f.Name(). Go nu îl șterge singur: pune defer os.Remove(f.Name()). Un tipar util este să scrii în fișierul temporar și apoi să-l redenumești peste fișierul final cu os.Rename; în acest caz creează-l în același director cu fișierul final.

Parametri

Parametru Descriere
dir Directorul în care se creează; "" = directorul temporar al sistemului.
pattern Modelul numelui; * marchează locul părții aleatorii.

Ce returnează

Fișierul deschis și nil, sau o eroare.

Exemple

Exemplul 1: Fișier de lucru șters la final

Numele conține o parte aleatorie, așa că verificăm doar începutul și sfârșitul lui.

package main

import (
    "fmt"
    "io"
    "os"
    "path/filepath"
    "strings"
)

func main() {
    f, err := os.CreateTemp("", "export-*.csv")
    if err != nil {
        fmt.Println("eroare:", err)
        return
    }
    defer os.Remove(f.Name())
    defer f.Close()

    fmt.Fprintln(f, "Ana,Iași")
    fmt.Fprintln(f, "Mihai,Cluj")
    f.Seek(0, io.SeekStart)
    date, _ := io.ReadAll(f)

    nume := filepath.Base(f.Name())
    fmt.Println(strings.HasPrefix(nume, "export-"), strings.HasSuffix(nume, ".csv"))
    fmt.Print(string(date))
    info, _ := f.Stat()
    fmt.Println("drepturi:", info.Mode())
}

Rezultat

true true
Ana,Iași
Mihai,Cluj
drepturi: -rw-------

Exemplul 2: Salvare atomică: temporar, apoi Rename

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func salveaza(nume string, date []byte) error {
    tmp, err := os.CreateTemp(".", nume+".tmp-*")
    if err != nil {
        return err
    }
    defer os.Remove(tmp.Name()) // nu face nimic dacă Rename a reușit
    if _, err := tmp.Write(date); err != nil {
        tmp.Close()
        return err
    }
    if err := tmp.Close(); err != nil {
        return err
    }
    return os.Rename(tmp.Name(), nume)
}

func main() {
    os.WriteFile("stoc.json", []byte(`{"cafea": 3}`), 0o644)
    fmt.Println(salveaza("stoc.json", []byte(`{"cafea": 12}`)))
    date, _ := os.ReadFile("stoc.json")
    fmt.Println(string(date))
    ramase, _ := filepath.Glob("stoc.json.tmp-*")
    fmt.Println("fișiere temporare rămase:", len(ramase))
}

Rezultat

<nil>
{"cafea": 12}
fișiere temporare rămase: 0

Greșeli frecvente

  • Uiți să ștergi fișierul temporar. Fișierele se adună în directorul temporar al sistemului.
  • Creezi fișierul temporar în os.TempDir() și apoi faci Rename pe alt disc: primești „invalid cross-device link”. Creează-l în directorul destinației.

Comenzi înrudite

  • os.MkdirTemp: Creează un director temporar nou, cu nume unic, și returnează calea lui.
  • os.TempDir: Returnează directorul pentru fișiere temporare al sistemului (de obicei /tmp pe Linux).
  • os.Rename: Redenumește sau mută un fișier ori un director.
  • os.Create: Creează un fișier nou (sau golește unul existent) și îl deschide pentru scriere și citire.
  • os.File.Name: Returnează numele cu care a fost deschis fișierul (calea dată la Open sau Create).