os.CopyFS în Go

Copiază tot conținutul unui sistem de fișiere (fs.FS) într-un director de pe disc.

Sintaxă
func CopyFS(dir string, fsys fs.FS) error

Ce face os.CopyFS

os.CopyFS copiază recursiv toate fișierele și directoarele din fsys în dir, creând dir dacă lipsește. Sursa poate fi un director de pe disc (os.DirFS), fișiere încorporate în program (embed.FS) sau o arhivă zip deschisă.

Funcția nu suprascrie fișiere existente: dacă un fișier există deja în destinație, se oprește cu o eroare pentru care errors.Is(err, fs.ErrExist) este true. Fișierele noi primesc drepturile 0o666 (plus execuția din sursă), apoi se aplică umask.

Parametri

Parametru Descriere
dir Directorul destinație.
fsys Sistemul de fișiere sursă (orice fs.FS).

Ce returnează

nil sau prima eroare întâlnită.

Exemple

Exemplul 1: Copierea unui director

package main

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

func main() {
    os.MkdirAll("site/css", 0o755)
    os.WriteFile("site/index.html", []byte("<h1>Bun venit</h1>"), 0o644)
    os.WriteFile("site/css/stil.css", []byte("body{margin:0}"), 0o644)

    if err := os.CopyFS("backup", os.DirFS("site")); err != nil {
        fmt.Println("eroare:", err)
        return
    }
    fs.WalkDir(os.DirFS("backup"), ".", func(cale string, d fs.DirEntry, err error) error {
        fmt.Println(cale)
        return nil
    })
}

Rezultat

.
css
css/stil.css
index.html

Exemplul 2: Nu suprascrie

package main

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

func main() {
    os.MkdirAll("sursa", 0o755)
    os.WriteFile("sursa/note.txt", []byte("nou"), 0o644)
    os.MkdirAll("dest", 0o755)
    os.WriteFile("dest/note.txt", []byte("vechi"), 0o644)

    err := os.CopyFS("dest", os.DirFS("sursa"))
    fmt.Println("eroare:", err)
    fmt.Println("există deja:", errors.Is(err, fs.ErrExist))
}

Rezultat

eroare: open dest/note.txt: file exists
există deja: true

Greșeli frecvente

  • Te aștepți ca o a doua copiere să actualizeze fișierele. CopyFS se oprește la primul fișier existent; șterge destinația înainte sau copiază fișier cu fișier.

Comenzi înrudite

  • os.DirFS: Transformă un director de pe disc într-un fs.FS, sistemul de fișiere abstract din Go.
  • embed.FS: Include fișiere și directoare direct în executabil la compilare, ca programul să nu mai depindă de fișiere externe.
  • filepath.WalkDir: Parcurge recursiv un director și apelează o funcție pentru fiecare fișier și subdirector, în ordine alfabetică.
  • io.Copy: Copiază toate datele dintr-un Reader într-un Writer, pe bucăți, fără să le țină pe toate în memorie.