Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. std::path::Path / PathBuf

std::path::Path / PathBuf

Since: Rust 1.0(2015)

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

MethodDescription
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

sample_path_pathbuf.rs
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);
    }

    let test_path = Path::new("test_path.txt");
    fs::write(test_path, "test").unwrap();
    println!("test_path exists: {}", test_path.exists()); // true
    println!("test_path is_file: {}", test_path.is_file()); // true
    fs::remove_file(test_path).unwrap();

    // 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);
    }
}

Compile with the following command:

rustc sample_path_pathbuf.rs
./sample_path_pathbuf
path: /home/user/documents/report.txt
app_log: /var/log/myapp/error.log
file_name: Some("report.txt")
file_stem: Some("report")
extension: Some("txt")
parent: Some("/home/user/documents")
current directory exists: true
is_dir: true
is_file: false
to_str: /home/user/documents/report.txt
test_path exists: true
test_path is_file: true
after change: archive.tar.bz2
component: RootDir
component: Normal("home")
component: Normal("user")
component: Normal("file.txt")

Common Mistakes

Common mistake 1: building paths with string concatenation

Concatenating strings with '/' to build paths can cause problems with OS-specific separators or double slashes. Use PathBuf and push() or join() instead.

let path = "/home/".to_string() + "user/" + "file.txt";

The same logic can also be written as:

use std::path::PathBuf;

let mut path = PathBuf::from("/home");
path.push("user");
path.push("file.txt");
println!("{}", path.display()); // /home/user/file.txt

Common mistake 2: unwrapping to_str() unconditionally

to_str() returns None when the path is not valid UTF-8. Calling unwrap() directly will panic on non-UTF-8 paths.

use std::path::Path;

// Panics on non-UTF-8 paths
let path = Path::new("/home/kiryu/file.txt");
let s = path.to_str().unwrap();

The same logic can also be written as:

use std::path::Path;

// Safe: handle the Option explicitly
let path = Path::new("/home/kiryu/file.txt");
match path.to_str() {
    Some(s) => println!("path: {}", s),
    None => println!("path is not valid UTF-8"),
}

// Or use display() which works for any path
println!("{}", path.display());

Common mistake 3: confusing Path and PathBuf ownership

Path is a borrowed reference (like &str) and cannot be stored in a struct without a lifetime. Use PathBuf (like String) when you need ownership.

use std::path::Path;

// Compile error: cannot store a borrowed Path without a lifetime annotation
// struct Config {
//     path: Path, // error: the size of `Path` cannot be known at compile-time
// }

The same logic can also be written as:

use std::path::PathBuf;

// Correct: use PathBuf for owned paths in structs
struct Config {
    path: PathBuf,
}

let config = Config {
    path: PathBuf::from("/home/kiryu/config.toml"),
};
println!("{}", config.path.display());

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 .