How to List Files in a Directory in Rust

Use the `std::fs::read_dir` function to iterate over directory entries, or `std::fs::read_dir` combined with `filter_map` to safely handle errors and extract paths.

Use the std::fs::read_dir function to iterate over directory entries, or std::fs::read_dir combined with filter_map to safely handle errors and extract paths. For a quick one-liner to print filenames, std::fs::read_dir paired with for loops is the standard approach.

Here is a practical example using read_dir to list files and directories, handling errors gracefully:

use std::fs;
use std::path::Path;

fn main() {
    let dir_path = Path::new("./src");

    match fs::read_dir(dir_path) {
        Ok(entries) => {
            for entry in entries {
                match entry {
                    Ok(entry) => {
                        let path = entry.path();
                        // Check if it's a file or directory
                        if path.is_file() {
                            println!("File: {:?}", path.file_name());
                        } else if path.is_dir() {
                            println!("Dir: {:?}", path.file_name());
                        }
                    }
                    Err(e) => eprintln!("Error reading entry: {}", e),
                }
            }
        }
        Err(e) => eprintln!("Error opening directory: {}", e),
    }
}

If you prefer a more functional style or need to filter specific file types (e.g., only .rs files), you can chain iterators with filter_map:

use std::fs;
use std::path::Path;

fn list_rust_files(dir: &Path) -> Vec<String> {
    fs::read_dir(dir)
        .expect("Failed to open directory")
        .filter_map(|entry| entry.ok())
        .filter(|entry| {
            entry.path().extension()
                .map(|ext| ext == "rs")
                .unwrap_or(false)
        })
        .map(|entry| entry.file_name().to_string_lossy().to_string())
        .collect()
}

fn main() {
    let rust_files = list_rust_files(Path::new("."));
    println!("Found {} Rust files:", rust_files.len());
    for file in rust_files {
        println!(" - {}", file);
    }
}

Key points to remember: read_dir returns an iterator of Result<DirEntry, Error>, so you must handle the Result for each entry to avoid panics if a file is deleted or permissions change during iteration. The DirEntry struct provides methods like path(), file_name(), and metadata() to inspect the entry without immediately reading the full file system metadata, which is efficient for large directories. If you need to sort the results, collect the iterator into a Vec first, then sort by the filename or path.