パスを扱う
ファイルパスを扱うには、Path
やPathBuf
を使います。前者はイミュータブルであり、後者は前者への参照にあたります(&str
とString
のような関係です)。
以降、std::path::Path
を単にPath
と表現します。
文字列からパスを取得する
Path::new(パス文字列)
で対応するパスを取得します。存在しないディレクトリを含んでいるとエラーになります。
また、Path
にはjoin
という便利なメソッドがあり、チェーンすることでパスを繋げていくことができます。ただし、途中で絶対パス(/foo/bar
のようなもの)を渡すと、そこでパスが上書きされるので注意しましょう。
use std::path::Path;
fn main() {
let path = Path::new("/home/user/documents");
println!("Path: {:?}", path);
let joined_path = path.join("subdir").join("file.txt");
println!("Joined Path: {:?}", joined_path);
let overwritten_path = path.join("/new/absolute/path");
println!("Overwritten Path: {:?}", overwritten_path);
}
PathBuf
にはpush
というメソッドもあり、join
と似たような挙動をします。join
は新たなPathBuf
を返すのに対し、push
はPathBuf
に変更を加えるという違いがあります。
use std::path::PathBuf;
fn main() {
let mut path_buf = PathBuf::from("/home/user");
path_buf.push("documents");
path_buf.push("file.txt");
println!("PathBuf with push: {:?}", path_buf);
}
カレントディレクトリを取得する
std::env::current_dir
と使うと、実行時のカレントディレクトリを取得できます。
use std::env;
fn main() {
match env::current_dir() {
Ok(current_dir) => println!("Current directory: {:?}", current_dir),
Err(e) => eprintln!("Failed to get current directory: {}", e),
}
}
ファイル名を変更する
PathBuf
のset_file_name
メソッドを使うと、そのパスが示しているファイルの名前を変更できます。
use std::path::PathBuf;
fn main() {
let mut path_buf = PathBuf::from("/home/user/documents/file.txt");
path_buf.set_file_name("new_file_name.txt");
println!("Updated PathBuf: {:?}", path_buf);
}
set_file_name
はPathBuf
のメソッドでありPath
にはありません。PathBuf
がミュータブルなのに関係しているんでしょうか・・・
ファイルを扱う
ファイルを開く
File::open
で指定したパスのファイルへのファイル参照を作成します。これは読み取り専用になり、io::Result<File>
型を返します。そのため、ファイル読み込みに成功したか失敗したかはmatch
などで判定できます。
use std::fs::File;
use std::io;
fn main() -> io::Result<()> {
let file_path = "example.txt";
match File::open(file_path) {
Ok(file) => println!("File opened successfully: {:?}", file),
Err(e) => eprintln!("Failed to open file: {}", e),
}
Ok(())
}
File
オブジェクトがスコープを抜けるとドロップされるので、明示的なファイルを閉じる(close)処理は必要ありません。
ファイルを読み取る
File
オブジェクトのread_to_string
メソッドで、ファイルの中身をString
オブジェクトに読み取ります。あらかじめString
オブジェクトを作成しておき、それへのミュータブルな参照(&mut
)を引数に渡します。
use std::fs::File;
use std::io::{self, Read};
fn main() -> io::Result<()> {
let file_path = "example.txt";
let mut file = File::open(file_path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
println!("File contents: {}", contents);
Ok(())
}
ファイルに書き込む
File::create
でファイルにバイト列の内容を書き込みます。渡したパスのファイルがすでに存在している場合、上書きされるので注意しましょう。
use std::fs::File;
use std::io::{self, Write};
fn main() -> io::Result<()> {
let file_path = "output.txt";
let mut file = File::create(file_path)?;
file.write_all(b"Hello, Rust!")?;
println!("File written successfully");
Ok(())
}