Rustでパスがフォルダがファイルかを判別する

はじめに

この記事では、「Rustでパスがフォルダがファイルかを判別する方法」について書いています。

Rustを色々勉強中ですが知らないことや学んだのに忘れてしまっていたこともまだたくさんあり、Rustの勉強も兼ねて記事を書きました。

自分に向けた備忘録でもありますが、「Rustでファイルやフォルダの扱い方を知りたい」な人の一助になれば嬉しいです。

前提(環境)

私の環境のバージョン情報は以下の通りです。

説明

早速ですが、コードを以下に記します。このコードは、実行ファイルがあるフォルダ内の全てのファイルと、それがファイルかフォルダなのかを表示(標準出力)します。

use std::path;

fn main() {
    let target_path = "./";
    let target = path::PathBuf::from(target_path);
    let files = target.read_dir().expect("このパスは存在しません");
    for dir_entry in files {
        let file_path = dir_entry.unwrap().path();

        let is_dir = file_path.is_dir();
        if is_dir {
            println!("{:?}: folder", file_path);
        } else {
            println!("{:?}: file", file_path);
        }
    }
}

このコードで重要なポイントはlet is_dir = file_path.is_dir();です。

is_dir()メソッドで、file_pathが示すパスがフォルダ(ディレクトリ)かそうでないかを判断することができます。

基本的にフォルダでない場合はファイルかと思いますが、std::pathのドキュメントを確認すると

パーミッション エラーやシンボリック リンクの破損などにより、ファイルのメタデータにアクセスできない場合はfalseを返す

とあるので、trueが返ってきたらフォルダ、falseが返ってきたら"フォルダではない"という認識の方が良いかもしれません。

コードの実行例

例えば以下の構成になっている、普通のRustプロジェクトで考えます。

sample
├ .git
│   └ ... (省略)
├ src
│   └ main.rs  <- 上のコードが記述されている
├ target
│   └ ... (省略)
├ .gitignore
├ Cargo.lock
└ Cargo.toml

この中でのポイントは.git.gitignoreです。.gitignoreはファイルなのに対して.gitはフォルダです。これらは見分けてくれるのでしょうか。

このRustプロジェクトでcargo runを実行(つまりsampleフォルダ上で上のコードを実行)した時の出力は見てみましょう。以下のようになります。

"./.git": folder
"./.gitignore": file
"./Cargo.lock": file
"./Cargo.toml": file
"./src": folder
"./target": folder

.gitfolder.gitignorefileと正しく認識されています。

おわりに

「Rustでパスがフォルダがファイルかを判別する方法」について解説しました。

Rustでツールを作りたい、作ろうとしている方の一助になれば幸いです。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

doc.rust-lang.org