std::path::Path / PathBuf
Rust uses std::path::Path and PathBuf for file path manipulation. Path is a borrowed, immutable path reference, while PathBuf is an owned, mutable path. Both automatically handle differences in path separators across operating systems.
Syntax
use std::path::{Path, PathBuf};
// Path — an immutable path reference (the path equivalent of &str)
let path = Path::new("/home/user/file.txt");
// PathBuf — an owned, mutable path (the path equivalent of String)
let mut buf = PathBuf::from("/home/user");
buf.push("documents"); // Appends a component to the path.
buf.push("file.txt");
// Joining paths (join returns a new PathBuf)
let full = Path::new("/home").join("user").join("file.txt");
// Retrieving path information
path.file_name() // "file.txt"
path.file_stem() // "file" (without extension)
path.extension() // "txt"
path.parent() // "/home/user"
path.exists() // Checks whether the file exists.
path.is_file() // Checks whether this is a file.
path.is_dir() // Checks whether this is a directory.
Method List
| Method | Description |
|---|---|
| Path::new(s) | Creates a Path reference from a string. |
| PathBuf::from(s) | Creates a PathBuf from a string. |
| path.join(p) | Returns a new PathBuf with the given component appended. |
| buf.push(p) | Appends a component to a PathBuf in place (mutable). |
| path.exists() | Returns true if the path exists on the filesystem. |
| path.is_file() | Returns true if the path points to a regular file. |
| path.is_dir() | Returns true if the path points to a directory. |
| path.file_name() | Returns the final component of the path as Option<&OsStr>. |
| path.file_stem() | Returns the file name without its extension. |
| path.extension() | Returns the file extension as Option<&OsStr>. |
| path.parent() | Returns the parent directory as Option<&Path>. |
| path.to_str() | Converts the path to &str (returns None if not valid UTF-8). |
| path.display() | Returns a display-friendly string representation (usable with println!). |
Sample Code
use std::path::{Path, PathBuf};
use std::fs;
fn main() {
// Build a path using PathBuf.
let mut path = PathBuf::from("/home");
path.push("user");
path.push("documents");
path.push("report.txt");
println!("path: {}", path.display());
// /home/user/documents/report.txt
// Join paths using join (the original path is unchanged).
let base = Path::new("/var/log");
let app_log = base.join("myapp").join("error.log");
println!("app_log: {}", app_log.display());
// /var/log/myapp/error.log
// Retrieve individual components of a path.
let file = Path::new("/home/user/documents/report.txt");
println!("file_name: {:?}", file.file_name()); // "report.txt"
println!("file_stem: {:?}", file.file_stem()); // "report"
println!("extension: {:?}", file.extension()); // "txt"
println!("parent: {:?}", file.parent()); // "/home/user/documents"
// Check existence and type.
let current = Path::new(".");
println!("current directory exists: {}", current.exists()); // true
println!("is_dir: {}", current.is_dir()); // true
println!("is_file: {}", current.is_file()); // false
// Convert to &str.
if let Some(s) = file.to_str() {
println!("to_str: {}", s);
}
// Create a test file and verify.
let test_path = Path::new("test_path.txt");
fs::write(test_path, "test")?;
println!("test_path exists: {}", test_path.exists()); // true
println!("test_path is_file: {}", test_path.is_file()); // true
fs::remove_file(test_path)?;
// Change the extension (PathBuf only).
let mut p = PathBuf::from("archive.tar.gz");
p.set_extension("bz2");
println!("after change: {}", p.display()); // archive.tar.bz2
// Iterate over path components.
for component in Path::new("/home/user/file.txt").components() {
println!("component: {:?}", component);
}
}
Notes
The relationship between Path and PathBuf mirrors the relationship between &str and String. Function parameters typically accept &Path or impl AsRef<Path>, allowing string literals, PathBuf, and other types to be passed interchangeably.
On Windows the path separator is \, and on Unix-like systems it is /. Rust's Path automatically uses the appropriate separator for the target OS, making it straightforward to write cross-platform code.
For reading and writing files, see std::fs::read_to_string() / write(). For fine-grained control using file handles, see File::open() / File::create().
If you find any errors or copyright issues, please contact us.