Rustでファイルを開く
Rustでファイルを操作して、書き込んだり読み込んだりする方法です。
以下について、簡単なコードを添えて書いています。
- ファイルを新規作成して書き込みする
- ファイルを開き、内容を読み込む
- 読み込みと書き込みを行う
- まとめ
ファイルを新規作成して書き込みする
std::fs::File::createを使ってファイルを作成してます。
作成したファイルへの書き込みは、write_allを使って行っています。
use std::fs::File;
use std::io::Write;
fn main() {
let filename = "hello.txt";
// 複数回実行した場合上書きされる
let mut file = match File::create(filename) {
Err(why) => panic!("Couldn't create {}: {}", filename, why),
Ok(file) => file,
};
let contents = "こんにちは、Rust!";
match file.write_all(contents.as_bytes()) {
Err(why) => panic!("Couldn't write \"{}\" to {}: {}", contents, filename, why),
Ok(_) => println!("finished"),
}
}hello.txtというファイルがソースコードと同じディレクトリに作成され、こんにちは、Rust!という文字列がファイルに書き込まれます。
ファイルを開き、内容を読み込む
ファイルの読み込みは、File::openを使って開いたファイルに対して、read_to_stringを実行します。
read_to_stringの引数に読み込んだ文字列を格納する変数の参照を渡すことで、その変数にファイルの中身が書き込まれます。
use std::fs::File;
use std::io::Read;
fn main() {
let filename = "hello.txt";
let mut file = match File::open(filename) {
Err(why) => panic!("Couldn't open {}: {}", filename, why),
Ok(file) => file,
};
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Err(why) => panic!("Couldn't read {}: {}", filename, why),
Ok(_) => (),
}
println!("contents: {}", contents);
}読み込みと書き込みを行う
std::fs::OpenOptionsを使うことで、もう少し細かくファイルの読み書きを制御することができます。
OpenOptionsのオブジェクトを作成して、ファイルを開く設定を行います。
以下の例では、ファイルがなければ新規作成し、読み込みと書き込み+追記可能な設定でファイルを開きます。
ファイル内容を標準出力に出した後、ファイルに1行追記するので、実行するたびにhello.txtの行が増えていきます。
use std::fs::OpenOptions;
use std::io::Read;
use std::io::Write;
fn main() {
let filename = "hello.txt";
// OpenOptionsでファイルの開き方を制御
let mut file = match OpenOptions::new()
.create(true)
.write(true)
.read(true)
.append(true)
.open(filename)
{
Err(why) => panic!("Couldn't open {}: {}", filename, why),
Ok(file) => file,
};
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Err(why) => panic!("Couldn't read {}: {}", filename, why),
Ok(_) => (),
}
println!("contents:\n{}", contents);
let contents = "こんにちは、Rust!\n";
match file.write_all(contents.as_bytes()) {
Err(why) => panic!("Couldn't write \"{}\" to {}: {}", contents, filename, why),
Ok(_) => println!("finished"),
}
}設定とOpenOptionsのメソッドと意味の対応は以下になります。
.create(true): ファイルを作成.write(true): 書き込み可能.read(true): 読み込み可能append(true): 追記するopen(<ファイル名>): <ファイル名>を開く
File::createで読み込もうとすると、エラーになる
File::createで開いたファイルは書き込み専用なので、読み込もうとするとエラーになります。
同様に、File::openで開いたファイルは、読み込み専用なので、書き込もうとするとエラーになります。
use std::fs::File;
use std::io::Read;
fn main() {
let filename = "hello.txt";
let mut file = match File::create(filename) {
Err(why) => panic!("Couldn't create {}: {}", filename, why),
Ok(file) => file,
};
// File::createは書き込み専用で開くのでエラーになる
// => "thread 'main' panicked at 'Couldn't read hello.txt: Bad file descriptor (os error 9)', src/main.rs:22:21"
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Err(why) => panic!("Couldn't read {}: {}", filename, why),
Ok(_) => println!("finished"),
}
}まとめ
File::createは書き込み専用でファイルを開くFile::openは読み込み専用でファイルを開くFile::createで複数回開くと上書きされる- 細かいファイルの開き方の指定は、
OpenOptionsを使って指定する
Rustでのファイルの開き方がなんとなくわかりました。
createで書き込み専用で開くのは、初めてで一瞬戸惑いましたが、確かに新規でファイル作成した時に読み込むケースは少ないと思うので、わかりやすくて良いなぁと思いました。