os.Rename în Go

Redenumește sau mută un fișier ori un director.

Sintaxă
func Rename(oldpath, newpath string) error

Ce face os.Rename

os.Rename schimbă numele unui fișier sau îl mută în alt director de pe același disc. Pe Linux și macOS, dacă newpath este un fișier existent, acesta este înlocuit.

Mutarea între discuri sau partiții diferite nu funcționează cu Rename (eroare „cross-device link”); acolo trebuie să copiezi fișierul și apoi să-l ștergi pe cel vechi.

Un truc des folosit: scrii datele într-un fișier temporar și apoi faci Rename peste fișierul final. Pe Unix înlocuirea este atomică: cine citește vede fie fișierul vechi, fie cel nou complet.

Parametri

Parametru Descriere
oldpath Calea actuală.
newpath Calea nouă (nume nou și/sau alt director).

Ce returnează

nil la succes sau o eroare *os.LinkError, care conține ambele căi.

Exemple

Exemplul 1: Redenumire și mutare

package main

import (
    "fmt"
    "os"
)

func main() {
    os.WriteFile("factura.pdf", []byte("..."), 0o644)
    os.Mkdir("arhiva", 0o755)

    fmt.Println(os.Rename("factura.pdf", "factura-1042.pdf"))
    fmt.Println(os.Rename("factura-1042.pdf", "arhiva/factura-1042.pdf"))

    intrari, _ := os.ReadDir("arhiva")
    for _, e := range intrari {
        fmt.Println("arhiva/" + e.Name())
    }
}

Rezultat

<nil>
<nil>
arhiva/factura-1042.pdf

Exemplul 2: Salvare sigură prin fișier temporar

Dacă programul se oprește în timpul scrierii, setari.json rămâne întreg, pentru că se înlocuiește abia la final.

package main

import (
    "fmt"
    "os"
)

func salveaza(nume string, date []byte) error {
    temp := nume + ".tmp"
    if err := os.WriteFile(temp, date, 0o644); err != nil {
        return err
    }
    return os.Rename(temp, nume)
}

func main() {
    os.WriteFile("setari.json", []byte(`{"tema":"luminoasa"}`), 0o644)
    if err := salveaza("setari.json", []byte(`{"tema":"intunecata"}`)); err != nil {
        fmt.Println("eroare:", err)
        return
    }
    date, _ := os.ReadFile("setari.json")
    fmt.Println(string(date))
}

Rezultat

{"tema":"intunecata"}

Exemplul 3: Fișierul sursă lipsește

package main

import (
    "fmt"
    "os"
)

func main() {
    err := os.Rename("poza.jpg", "vacanta.jpg")
    fmt.Println(err)
}

Rezultat

rename poza.jpg vacanta.jpg: no such file or directory

Greșeli frecvente

  • Muți între partiții (de exemplu din /tmp pe alt disc) și primești „invalid cross-device link”. Copiază cu io.Copy, apoi șterge originalul.
  • Te aștepți ca Rename să creeze directorul destinație. Directorul trebuie să existe deja.

Comenzi înrudite

  • os.Remove: Șterge un fișier sau un director gol.
  • os.Link: Creează o legătură hard: un al doilea nume pentru același fișier de pe disc.
  • os.WriteFile: Scrie octeții dați într-un fișier: îl creează dacă lipsește și îi înlocuiește conținutul dacă există.
  • io.Copy: Copiază toate datele dintr-un Reader într-un Writer, pe bucăți, fără să le țină pe toate în memorie.