パスを扱う
ファイルパスを扱うには、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(())
}