os.File.ReadDir în Go

Citește intrările (fișiere și subdirectoare) dintr-un director deschis.

Sintaxă
func (f *File) ReadDir(n int) ([]DirEntry, error)

Ce face os.File.ReadDir

Pe un director deschis cu os.Open, ReadDir returnează intrările lui ca []os.DirEntry. Fiecare intrare are Name(), IsDir(), Type() și Info().

Cu n <= 0 primești toate intrările dintr-o dată, în ordinea din sistemul de fișiere (nesortate). Cu n > 0 primești cel mult n la fiecare apel, util pentru directoare uriașe; la final primești io.EOF.

Funcția os.ReadDir(nume) (fără fișier deschis) este mai simplă pentru cazul obișnuit și returnează intrările sortate după nume.

Parametri

Parametru Descriere
n Câte intrări să citească; 0 sau negativ = toate.

Ce returnează

Intrările citite și nil; la n > 0, după ultima intrare, un slice gol și io.EOF.

Exemple

Exemplul 1: Toate intrările, sortate

package main

import (
    "fmt"
    "os"
    "slices"
    "strings"
)

func main() {
    os.MkdirAll("proiect/docs", 0o755)
    os.WriteFile("proiect/main.go", nil, 0o644)
    os.WriteFile("proiect/go.mod", nil, 0o644)

    d, err := os.Open("proiect")
    if err != nil {
        fmt.Println("eroare:", err)
        return
    }
    defer d.Close()

    intrari, _ := d.ReadDir(0)
    slices.SortFunc(intrari, func(a, b os.DirEntry) int { return strings.Compare(a.Name(), b.Name()) })
    for _, e := range intrari {
        tip := "fișier"
        if e.IsDir() {
            tip = "director"
        }
        fmt.Printf("%-8s %s\n", e.Name(), tip)
    }
}

Rezultat

docs     director
go.mod   fișier
main.go  fișier

Exemplul 2: Citire în loturi

Numărăm fișierele câte 4 deodată, ca la un director cu foarte multe intrări. Ultimul apel returnează un lot gol și io.EOF.

package main

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

func main() {
    os.Mkdir("poze", 0o755)
    for i := 1; i <= 10; i++ {
        os.WriteFile(fmt.Sprintf("poze/img%02d.jpg", i), nil, 0o644)
    }

    d, _ := os.Open("poze")
    defer d.Close()
    total := 0
    for {
        lot, err := d.ReadDir(4)
        total += len(lot)
        fmt.Println("lot de", len(lot))
        if errors.Is(err, io.EOF) {
            break
        }
    }
    fmt.Println("total:", total)
}

Rezultat

lot de 4
lot de 4
lot de 2
lot de 0
total: 10

Greșeli frecvente

  • Te aștepți ca f.ReadDir să returneze intrările sortate. Nu le sortează; os.ReadDir le sortează.
  • Apelezi ReadDir pe un fișier obișnuit; primești eroare „not a directory”.

Comenzi înrudite

  • os.File: Tipul care reprezintă un fișier deschis; îl obții cu os.Open, os.Create sau os.OpenFile.
  • filepath.WalkDir: Parcurge recursiv un director și apelează o funcție pentru fiecare fișier și subdirector, în ordine alfabetică.
  • filepath.Glob: Returnează toate fișierele de pe disc ale căror nume se potrivesc unui model cu *, ? și [ ].
  • os.Mkdir: Creează un singur director nou; dă eroare dacă există deja sau dacă directorul părinte lipsește.
  • os.ReadDir: Returnează conținutul unui director (fișiere și subdirectoare), sortat după nume.