os.Stat în Go

Returnează informațiile unui fișier (dimensiune, drepturi, dată, director sau nu) fără să-l deschidă; Lstat nu urmează legăturile.

Sintaxă
func Stat(name string) (FileInfo, error)
func Lstat(name string) (FileInfo, error)

Ce face os.Stat

os.Stat returnează un os.FileInfo cu metodele Name(), Size() (în octeți), Mode() (tipul și drepturile), ModTime() (data ultimei modificări) și IsDir(). Fișierul nu este deschis și nici citit.

Este și modul obișnuit de a verifica existența: _, err := os.Stat(cale), apoi errors.Is(err, fs.ErrNotExist). Atenție, între verificare și folosire fișierul se poate schimba; dacă oricum îl deschizi, tratează direct eroarea lui Open.

Dacă name este o legătură simbolică, Stat o urmează și descrie fișierul țintă. os.Lstat descrie legătura însăși: Mode()&os.ModeSymlink != 0. Pentru un fișier deja deschis există metoda f.Stat().

Parametri

Parametru Descriere
name Calea fișierului sau a directorului.

Ce returnează

Un FileInfo și nil, sau nil și o eroare *fs.PathError.

Exemple

Exemplul 1: Informații despre un fișier și un director

package main

import (
    "fmt"
    "os"
    "time"
)

func main() {
    os.Mkdir("facturi", 0o755)
    os.WriteFile("facturi/1042.pdf", make([]byte, 3500), 0o644)
    t := time.Date(2025, time.March, 14, 9, 30, 0, 0, time.UTC)
    os.Chtimes("facturi/1042.pdf", t, t)

    for _, cale := range []string{"facturi/1042.pdf", "facturi"} {
        info, err := os.Stat(cale)
        if err != nil {
            fmt.Println("eroare:", err)
            continue
        }
        fmt.Printf("%-10s director: %-5v ", info.Name(), info.IsDir())
        if !info.IsDir() {
            fmt.Printf("%d octeți, modificat %s", info.Size(), info.ModTime().UTC().Format("02.01.2006 15:04"))
        }
        fmt.Println()
    }
}

Rezultat

1042.pdf   director: false 3500 octeți, modificat 14.03.2025 09:30
facturi    director: true

Exemplul 2: Există sau nu?

package main

import (
    "errors"
    "fmt"
    "io/fs"
    "os"
)

func exista(cale string) (bool, error) {
    _, err := os.Stat(cale)
    if err == nil {
        return true, nil
    }
    if errors.Is(err, fs.ErrNotExist) {
        return false, nil
    }
    return false, err // altă problemă, de exemplu lipsă drepturi
}

func main() {
    os.WriteFile("setari.json", []byte("{}"), 0o644)
    for _, f := range []string{"setari.json", "setari.local.json"} {
        ok, err := exista(f)
        fmt.Println(f, ok, err)
    }
}

Rezultat

setari.json true <nil>
setari.local.json false <nil>

Exemplul 3: Stat față de Lstat pe o legătură simbolică

package main

import (
    "fmt"
    "os"
)

func main() {
    os.WriteFile("catalog-2025.csv", make([]byte, 1200), 0o644)
    os.Symlink("catalog-2025.csv", "catalog.csv")

    s, _ := os.Stat("catalog.csv")
    l, _ := os.Lstat("catalog.csv")
    fmt.Println("Stat: ", s.Mode(), s.Size(), "octeți")
    fmt.Println("Lstat:", l.Mode(), "| legătură:", l.Mode()&os.ModeSymlink != 0)

    _, err := os.Lstat("lipsa.csv")
    fmt.Println(err)
}

Rezultat

Stat:  -rw-r--r-- 1200 octeți
Lstat: Lrwxr-xr-x | legătură: true
lstat lipsa.csv: no such file or directory

Greșeli frecvente

  • Scrii if _, err := os.Stat(f); err != nil { /* nu există */ }. Și alte erori (lipsă drepturi) intră aici; verifică fs.ErrNotExist.
  • Folosești Stat ca să verifici o legătură simbolică ruptă: Stat dă eroare (ținta lipsește), deși legătura există. Folosește Lstat.
  • Verifici cu Stat și creezi apoi fișierul. Între timp alt proces îl poate crea; pentru creare sigură folosește os.OpenFile cu O_EXCL.

Comenzi înrudite

  • os.File.Stat: Returnează informații despre fișierul deschis: nume, dimensiune, drepturi, data modificării, dacă e director.
  • os.IsNotExist: IsNotExist spune dacă o eroare înseamnă „fișierul nu există”; IsExist, dacă înseamnă „există deja”.
  • os.Symlink: Creează o legătură simbolică (scurtătură) spre alt fișier; Readlink citește spre ce arată.
  • os.ReadDir: Returnează conținutul unui director (fișiere și subdirectoare), sortat după nume.
  • os.SameFile: Spune dacă două FileInfo descriu același fișier de pe disc, chiar dacă au căi diferite.