Question
How can I list all files in a directory in Rust?
I am looking for the Rust equivalent of the following Python code:
import os
copyfiles = os.listdir('./')
Short Answer
By the end of this page, you will understand how to read directory contents in Rust using std::fs::read_dir, how to extract file names and paths, how to handle errors safely, and how to filter results when you only want files rather than directories.
Concept
In Rust, listing the contents of a directory is usually done with std::fs::read_dir.
read_dir returns an iterator over the entries inside a directory. Each entry is represented by a DirEntry, which can give you information such as:
- the full path
- the file name
- metadata about the entry
This matters because many real programs need to inspect folders:
- command-line tools that scan files
- backup scripts
- media organizers
- build systems
- log processors
Unlike Python's os.listdir, Rust makes error handling explicit. That means:
- opening the directory can fail
- reading a specific entry can fail
- converting a file name to a UTF-8 string may fail in some cases
Rust asks you to deal with those possibilities clearly, which leads to safer code.
Mental Model
Think of a directory like a box of labeled items.
read_dir("./")opens the box- the iterator lets you pull items out one by one
- each
DirEntryis one item label - you can inspect that label to get the name or full path
So instead of getting one finished list immediately, Rust often gives you a stream of entries that you process step by step.
Syntax and Examples
The basic syntax is:
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
let entry = entry?;
println!("{}", entry.path().display());
}
Ok(())
}
What this does
fs::read_dir("./")?opens the current directory- it returns an iterator of results
- each
entrymust also be unwrapped with? entry.path()gets the full path.display()formats the path for printing
Getting only file names
use std::fs;
fn main() -> std::io::Result<()> {
for fs::()? {
= entry?;
= entry.();
(, file_name.());
}
(())
}
Step by Step Execution
Consider this example:
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
let entry = entry?;
println!("{}", entry.file_name().to_string_lossy());
}
Ok(())
}
Step by step:
-
fs::read_dir("./")?- Rust tries to open the current directory.
- If it fails,
mainreturns the error immediately.
-
for entry in ...- Rust starts looping over the directory entries.
- Each item is a
Result<DirEntry, std::io::Error>.
-
let entry = entry?;- If reading this specific entry failed, return the error.
- Otherwise, extract the
DirEntry.
Real World Use Cases
Directory listing is used in many practical situations:
- CLI tools: scan a folder and process every file
- Backup utilities: gather files before copying them elsewhere
- Image or video apps: load media files from a directory
- Log analysis: read all log files in a folder
- Static site generators: find content files to build pages
- Build tools: inspect source directories for compilation inputs
Example: only process .txt files in a folder.
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
let entry = entry?;
let path = entry.path();
if path.extension().and_then(|ext| ext.to_str()) == Some("txt") {
println!("Text file: {}", path.display());
}
}
Ok(())
}
This pattern is common in scripts and automation tools.
Real Codebase Usage
In real Rust codebases, developers usually do more than just print entries.
Common patterns include:
Guard clauses
Return early if the directory cannot be read:
use std::fs;
fn list_dir(path: &str) -> std::io::Result<()> {
let entries = fs::read_dir(path)?;
for entry in entries {
let entry = entry?;
println!("{}", entry.path().display());
}
Ok(())
}
Filtering only files
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
let entry = entry?;
let path = entry.();
path.() {
(, path.());
}
}
(())
}
Common Mistakes
1. Forgetting that read_dir returns results
Broken code:
use std::fs;
fn main() {
for entry in fs::read_dir("./") {
println!("{:?}", entry);
}
}
Problem:
fs::read_dir("./")returns aResult<ReadDir, Error>, not an iterator directly.
Correct version:
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
println!("{:?}", entry?);
}
Ok(())
}
2. Assuming every name is valid UTF-8
Broken code:
= entry.().().();
Comparisons
| Concept | Rust | Python | Notes |
|---|---|---|---|
| List directory contents | fs::read_dir("./") | os.listdir("./") | Rust returns an iterator of results instead of a plain list |
| File name only | entry.file_name() | names returned directly | Rust uses OS-specific string types |
| Full path | entry.path() | often built with os.path.join(...) | Rust can give the full path directly |
| Error handling | Result, ? | exceptions | Rust makes failure explicit |
Cheat Sheet
use std::fs;
fn main() -> std::io::Result<()> {
for entry in fs::read_dir("./")? {
let entry = entry?;
println!("{}", entry.path().display());
}
Ok(())
}
Quick rules
- Use
std::fs::read_dir(path)to read a directory. - It returns
Result<ReadDir, std::io::Error>. - Each item inside the iterator is also a
Result<DirEntry, std::io::Error>. - Use
entry.path()for full path. - Use
entry.file_name()for just the file name. - Use
to_string_lossy()for safe string conversion. - Use
path.is_file()to keep only files. - Use
path.is_dir()to keep only directories.
Common patterns
Get file names:
FAQ
How do I list files in the current directory in Rust?
Use std::fs::read_dir("./") and loop through the returned entries.
What is the Rust equivalent of Python os.listdir()?
The closest equivalent is std::fs::read_dir(). Rust returns an iterator of directory entries rather than a ready-made list of strings.
How do I get only file names and not full paths?
Use entry.file_name() instead of entry.path().
How do I list only regular files in Rust?
Check entry.path().is_file() before processing the entry.
Why does Rust use OsString for file names?
Because file names are not always valid UTF-8 on all operating systems. OsString can represent OS-native file names safely.
Can read_dir fail even after opening the directory?
Yes. Opening the directory may succeed, but reading a specific entry can still fail, which is why each entry is also a Result.
How do I collect directory contents into a vector?
Use a loop with push, or use iterator methods like and .
Mini Project
Description
Build a small Rust program that scans a directory and prints only regular files. This demonstrates how to read directory entries, filter out folders, and collect file names into a vector for later use. This kind of task appears in backup scripts, media tools, and command-line utilities.
Goal
Create a Rust program that lists only the files in the current directory and stores their names in a vector.
Requirements
Requirement 1
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.