fs::read_dir în Rust

Listează intrările (fișiere și directoare) dintr-un director, ca iterator de DirEntry.

Sintaxă
pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir>
// ReadDir: Iterator<Item = io::Result<DirEntry>>

Ce face fs::read_dir

fs::read_dir(".") returnează un iterator. Fiecare element este un io::Result<DirEntry>; pe un DirEntry ai file_name() (doar numele), path() (calea completă), file_type() și metadata().

Ordinea intrărilor nu este garantată: depinde de sistemul de fișiere. Dacă vrei o listă stabilă, adună numele într-un vector și sortează-l. Intrările speciale . și .. nu apar. Funcția nu intră în subdirectoare; pentru asta o apelezi recursiv.

Parametri

Parametru Descriere
path Directorul de listat.

Ce returnează

io::Result<ReadDir>, un iterator peste io::Result<DirEntry>.

Exemple

Exemplul 1: Lista sortată a fișierelor

use std::fs;

fn main() -> std::io::Result<()> {
    fs::create_dir_all("poze/vacanta")?;
    for nume in ["c.txt", "a.txt", "b.csv"] {
        fs::write(format!("poze/{nume}"), "x")?;
    }

    let mut intrari = Vec::new();
    for intrare in fs::read_dir("poze")? {
        let intrare = intrare?;
        let tip = if intrare.file_type()?.is_dir() { "director" } else { "fișier" };
        intrari.push(format!("{} ({tip})", intrare.file_name().to_string_lossy()));
    }
    intrari.sort();
    for i in intrari {
        println!("{i}");
    }
    Ok(())
}

Rezultat

a.txt (fișier)
b.csv (fișier)
c.txt (fișier)
vacanta (director)

Exemplul 2: Parcurgere recursivă și filtrare după extensie

Funcția se apelează singură pentru fiecare subdirector și adună căile fișierelor .txt.

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

fn gaseste_txt(dir: &Path, rezultat: &mut Vec<PathBuf>) -> io::Result<()> {
    for intrare in fs::read_dir(dir)? {
        let cale = intrare?.path();
        if cale.is_dir() {
            gaseste_txt(&cale, rezultat)?;
        } else if cale.extension().is_some_and(|e| e == "txt") {
            rezultat.push(cale);
        }
    }
    Ok(())
}

fn main() -> io::Result<()> {
    fs::create_dir_all("proiect/docs/vechi")?;
    fs::write("proiect/citeste.txt", "")?;
    fs::write("proiect/main.rs", "")?;
    fs::write("proiect/docs/ghid.txt", "")?;
    fs::write("proiect/docs/vechi/note.txt", "")?;

    let mut gasite = Vec::new();
    gaseste_txt(Path::new("proiect"), &mut gasite)?;
    gasite.sort();
    for cale in &gasite {
        println!("{}", cale.display());
    }
    Ok(())
}

Rezultat

proiect/citeste.txt
proiect/docs/ghid.txt
proiect/docs/vechi/note.txt

Greșeli frecvente

  • Afișezi intrările în ordinea primită și te aștepți la ordine alfabetică: ordinea diferă între sisteme. Sortează.
  • Uiți că fiecare element este un Result: for e in fs::read_dir(".")? { e.path() } nu compilează; scrie e?.path().

Comenzi înrudite

  • fs::metadata: Informații despre un fișier sau director: dimensiune, tip, permisiuni, data modificării.
  • Path::extension: extension() dă extensia fișierului (după ultimul punct), file_name() ultima parte a căii, fără directoare.
  • Path::exists: Întreabă sistemul dacă la cale există ceva (exists), dacă este un fișier (is_file) sau un director (is_dir).
  • fs::create_dir_all: Creează un director împreună cu toți părinții lui care lipsesc; nu dă eroare dacă directorul există deja.