18
10

More than 1 year has passed since last update.

Rustのファイルパスの扱いが複雑すぎる件

Last updated at Posted at 2021-07-22

Rustでファイル一覧を得ようとしたら、かなり複雑でこんがらがったので整理してみる。

ファイル一覧を得る

ファイル一覧を得るには、std::fs::read_dirを使う。

read_dir.rs
let dirname = "./hoge";
let files = fs::read_dir(dirname).unwrap();
for entry in files {
    let path = dir_entry.unwrap().path();
    println!("{:?}", path);
}

ただし、forで反復する要素は、Resultとなる。そこで、unwrapしてpathを得ることで、いろいろな操作が可能。

全ファイル列挙

サブフォルダも含めて列挙するには ... PathBufを得て、is_dir()などで再帰的に呼び出せば良さそう。

read_all_dir.rs
use std::path;

fn main() {
  let traget = path:PathBuf::from("./");
  enumfiles(&target);
}

fn enumfiles(target: &path::PathBuf) {
    // ファイル一覧を取得
    let files = target.read_dir().unwrap();
    for dir_entry in files {
        // PathBufを得る
        let path = dir_entry.unwrap().path();
        // ディレクトリか?
        if path.is_dir() {
            // 再帰的に検索
            enumfiles(&path, keyword);
            continue;
        }
        // ファイル名を表示
        println!("{}", path.to_str().unwrap());
    }
}

こんな感じかな?

さらに詳しく調べるには、metadata()などを呼び出して、各種パラメータを得よう。

ファイル名を文字列に変換する

ただし、ファイル名などを取得する場合、OSStringを返してくる。これをRustのStringに変換する際、UTF-8チェックが行われる。もし不正なUnicodeがあると、そこでエラーが出る。

for dir_entry in target.read_dir()? {
  let path = dir_entry().unwrap().path();
  let fname = path.file_name().unwrap()
    .to_str().unwrap();
}

そこで、to_string_lossyを使うことができる。すると正しいUnicodeを得ることができる。

for dir_entry in target.read_dir()? {
  let path = dir_entry().unwrap().path();
  let fname = path.file_name().unwrap()
    .to_string_lossy();
}

DirEntryの主要なメソッド

  • path(&self) -> PathBuf
  • 以下の PathBuf を得る
  • file_name(&self) -> OsString
  • file_type(&self) -> Result
    • FileTypeにはis_file/is_dirのメソッドがある

PathBufの主要なメソッド

std::path::PathBuf

  • ファイル名や拡張子を得る
  • file_name(&self) -> Option<&[OSStr](https://doc.rust-lang.org/std/ffi/struct.OsStr.html)>
  • extension(&self) -> Option<&OSStr>
  • 他の型に変換
  • as_os_str(&self) -> &OsStr
  • to_str(&self) -> Option<&str>
  • as_path(&self) -> &Path
  • display(&self) -> Display<'_>
  • 各種情報を得る
  • metadata(&self) -> Result
  • 日時やディレクトリなどのメタデータを得る
  • read_dir(&self) -> Result
  • parent(&self) -> Option<&Path>
  • 存在確認など
  • exists(&self) -> bool
  • is_file(&self) -> bool
  • is_dir(&self) -> bool

Metadataの主なメソッド

std::fs:Metadata

  • permissions(&self) -> Permissions
  • is_dir(&self) -> bool
  • file_type(&self) -> FileType
  • is_file(&self) -> bool
  • modified(&self) -> Result< SystemTime >
  • accessed(&self) -> Result< SystemTime >
  • created(&self) -> Result< SystemTime >
18
10
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
10