read_dir 関数の基本
Rust の標準モジュール std::fs
の read_dir 関数 を使うと、ディレクトリ内のファイルやディレクトリを列挙することができます。
列挙結果には、カレントディレクトリ (.
) や親ディレクトリ (..
) は含まれないので、自然な列挙が可能です。
エラーチェックする
上記ではコードを簡素化するために Result#unwrap
メソッドを使っていますが、万が一 Err
値が返された場合は panic が発生してしまうので、プロダクトコードでは unwrap
メソッドは使うべきではありません。
Result
が Ok
値を持っているかを調べつつ、その値を取り出すには、次のように if let
構文を使用できます。
Path インスタンスを取得する
DirEntry#file_name()
でファイル名 (OsString
) を取得する代わりに、DirEntry#path()
を使って PathBuf
オブジェクトを取得できます。
PathBuf
は、パス情報を扱ういろいろなメソッドを提供しています。
let path = entry.path(); // PathBuf を取得
println!("file_name = {:?}", entry.file_name());
println!("is_file = {}", path.is_file());
println!("is_dir = {}", path.is_dir());
println!("is_absolute = {}", path.is_absolute());
- 参考: ファイルやディレクトリの存在を調べる (
std::io::Path
,PathBuf
) - 参考: ファイルやディレクトリのパス文字列を構築/分割する (
std::path::Path
,PathBuf
)
ディレクトリ内のファイルリストを Vec で取得する
前述のように、Rust でディレクトリ内のファイルを列挙しようとすうと、少し面倒なコードになります。
下記のユーティリティ関数 read_dir_entries
を使うと、指定したディレクトリに含まれているファイルやディレクトリの名前 (PathBuf
) を Vec
形式でまとめて取得できます。
use std::{
fs, io,
path::{Path, PathBuf},
};
/** 指定したディレクトリ内のすべてのファイル(ディレクトリ)のパス情報を取得します。 */
fn read_dir_entries<P: AsRef<Path>>(path: P) -> io::Result<Vec<PathBuf>> {
let mut entries = fs::read_dir(path)?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<_>, io::Error>>()?;
entries.sort();
Ok(entries)
}
fn main() {
match read_dir_entries(".") {
Ok(entries) => println!("{:?}", entries),
Err(e) => eprintln!("ERROR: {}", e),
}
}