Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Rust辞典

  1. トップページ
  2. Rust辞典
  3. std::path::Path / PathBuf

std::path::Path / PathBuf

Rustのファイルパス操作には『std::path::Path』と『PathBuf』を使います。『Path』は借用された不変のパス参照、『PathBuf』は所有権を持つ可変のパスで、OS間のパス区切り文字の違いを自動的に吸収します。

構文
use std::path::{Path, PathBuf};

// Path — 不変のパス参照(&str のパス版)
let path = Path::new("/home/user/file.txt");

// PathBuf — 所有権を持つ可変のパス(String のパス版)
let mut buf = PathBuf::from("/home/user");
buf.push("documents");    // パスを追加します。
buf.push("file.txt");

// パスの結合(join は新しい PathBuf を返します)
let full = Path::new("/home").join("user").join("file.txt");

// パスの情報取得
path.file_name()          // "file.txt"
path.file_stem()          // "file"(拡張子なし)
path.extension()          // "txt"
path.parent()             // "/home/user"
path.exists()             // ファイルの存在確認
path.is_file()            // ファイルかどうか
path.is_dir()             // ディレクトリかどうか
メソッド一覧
メソッド概要
Path::new(s)文字列から Path への参照を作成します。
PathBuf::from(s)文字列から PathBuf を作成します。
path.join(p)パスを結合した新しい PathBuf を返します。
buf.push(p)PathBuf にパスを追加します(可変操作)。
path.exists()パスが存在するかを確認します。bool を返します。
path.is_file()通常ファイルかどうかを確認します。
path.is_dir()ディレクトリかどうかを確認します。
path.file_name()ファイル名部分を Option<&OsStr> で返します。
path.file_stem()拡張子を除いたファイル名を返します。
path.extension()拡張子を Option<&OsStr> で返します。
path.parent()親ディレクトリを Option<&Path> で返します。
path.to_str()パスを &str に変換します(UTF-8 でない場合は None)。
path.display()表示用の文字列表現を返します(println! で使えます)。
サンプルコード
use std::path::{Path, PathBuf};
use std::fs;

fn main() {
    // 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 でパスを結合します(元のパスは変わりません)。
    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

    // パスの各部分を取得します。
    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"

    // 存在確認と種類判定
    let current = Path::new(".");
    println!("カレントディレクトリ exists: {}", current.exists());  // true
    println!("is_dir: {}", current.is_dir());                      // true
    println!("is_file: {}", current.is_file());                    // false

    // &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")?;
    println!("test_path exists: {}", test_path.exists());  // true
    println!("test_path is_file: {}", test_path.is_file()); // true
    fs::remove_file(test_path)?;

    // 拡張子の変更(PathBuf のみ)
    let mut p = PathBuf::from("archive.tar.gz");
    p.set_extension("bz2");
    println!("変更後: {}", p.display());  // archive.tar.bz2

    // Path からのコンポーネント取得
    for component in Path::new("/home/user/file.txt").components() {
        println!("component: {:?}", component);
    }
}
概要

『Path』と『PathBuf』の関係は『&str』と『String』の関係と同じです。関数の引数では通常『&Path』か『impl AsRef<Path>』を受け取ることで、文字列リテラルや『PathBuf』など様々な型を受け入れられます。

Windows では区切り文字が『\』、Unix 系では『/』ですが、Rust の Path は OS に応じて自動的に適切な区切り文字を使うため、クロスプラットフォームのコードが書きやすくなっています。

ファイルの読み書きはstd::fs::read_to_string() / write()を、ファイルハンドルによる詳細な操作はFile::open() / File::create()を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。