Use the std::fs::create_dir_all function to create a directory and any missing parent directories in a single call. Unlike create_dir, which fails if parent directories don't exist, create_dir_all handles the entire path hierarchy atomically and returns an error only if the operation fails due to permissions or invalid paths.
Here is a practical example creating a nested path, followed by a command-line tool snippet:
use std::fs;
use std::path::Path;
fn main() -> std::io::Result<()> {
let path = "data/logs/2023-10-27/debug";
// Creates 'data', 'logs', '2023-10-27', and 'debug' if they don't exist
fs::create_dir_all(path)?;
// Verify creation
if Path::new(path).exists() {
println!("Successfully created directory tree: {}", path);
}
Ok(())
}
For a CLI tool where you might want to handle errors gracefully without crashing immediately, you can wrap the call in a match or if let block:
use std::fs;
use std::io;
fn ensure_directory(path: &str) -> io::Result<()> {
match fs::create_dir_all(path) {
Ok(()) => {
println!("Directory structure ready at: {}", path);
Ok(())
}
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {
// Directory already exists, which is usually fine
println!("Directory already exists: {}", path);
Ok(())
}
Err(e) => {
eprintln!("Failed to create directory '{}': {}", path, e);
Err(e)
}
}
}
Key considerations for production code:
- Permissions: If the parent directory exists but is read-only,
create_dir_allwill fail with a permission error. - Idempotency: The function is idempotent; calling it on an existing directory returns
Ok(())without error. - Symbolic Links: If the path contains a symbolic link that points to a non-directory, the function will fail.
- Atomicity: While it creates all parents, it is not strictly atomic across filesystem boundaries; if the process is killed mid-operation, you might end up with a partial directory tree.
Always use ? or explicit error handling to propagate failures, as silently ignoring errors can lead to runtime panics later when your code attempts to write files to a non-existent path.