os.SameFile în Go

Spune dacă două FileInfo descriu același fișier de pe disc, chiar dacă au căi diferite.

Sintaxă
func SameFile(fi1, fi2 FileInfo) bool

Ce face os.SameFile

os.SameFile compară identitatea fișierelor (pe Unix: dispozitivul și numărul inode), nu numele sau conținutul. Două căi scrise diferit (a.txt și dir/../a.txt) sau o legătură hard dau true.

Primește valori FileInfo obținute cu os.Stat (sau Lstat). Două fișiere diferite cu același conținut dau false.

Parametri

Parametru Descriere
fi1, fi2 Informațiile despre fișiere, din os.Stat, os.Lstat sau f.Stat().

Ce returnează

true dacă este același fișier, altfel false.

Exemple

Exemplul 1: Căi diferite, același fișier

package main

import (
    "fmt"
    "os"
)

func main() {
    os.Mkdir("date", 0o755)
    os.WriteFile("clienti.csv", []byte("Ana,Iași\n"), 0o644)
    os.WriteFile("copie.csv", []byte("Ana,Iași\n"), 0o644)

    a, _ := os.Stat("clienti.csv")
    b, _ := os.Stat("date/../clienti.csv")
    c, _ := os.Stat("copie.csv")

    fmt.Println("clienti.csv vs date/../clienti.csv:", os.SameFile(a, b))
    fmt.Println("clienti.csv vs copie.csv:", os.SameFile(a, c))
}

Rezultat

clienti.csv vs date/../clienti.csv: true
clienti.csv vs copie.csv: false

Exemplul 2: Evitarea copierii unui fișier peste el însuși

package main

import (
    "fmt"
    "os"
)

func copiaza(sursa, dest string) error {
    a, err := os.Stat(sursa)
    if err != nil {
        return err
    }
    if b, err := os.Stat(dest); err == nil && os.SameFile(a, b) {
        return fmt.Errorf("%s și %s sunt același fișier", sursa, dest)
    }
    date, err := os.ReadFile(sursa)
    if err != nil {
        return err
    }
    return os.WriteFile(dest, date, 0o644)
}

func main() {
    os.WriteFile("poza.jpg", []byte("..."), 0o644)
    fmt.Println(copiaza("poza.jpg", "backup.jpg"))
    fmt.Println(copiaza("poza.jpg", "./poza.jpg"))
}

Rezultat

<nil>
poza.jpg și ./poza.jpg sunt același fișier

Greșeli frecvente

  • Compari căile ca text (a == b) ca să vezi dacă e același fișier. Căile pot fi scrise diferit sau pot fi legături; folosește SameFile.

Comenzi înrudite

  • os.File.Stat: Returnează informații despre fișierul deschis: nume, dimensiune, drepturi, data modificării, dacă e director.
  • os.Link: Creează o legătură hard: un al doilea nume pentru același fișier de pe disc.
  • filepath.Clean: Simplifică o cale: elimină separatoarele duble, „.” și rezolvă „..” doar din text, fără acces la disc.