MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Rustの基礎 - ディレクトリのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Rustの基礎 - ディレクトリ
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == ディレクトリに含まれるファイルの一覧を取得したり、ディレクトリ名を変更したりすることができる。<br> ディレクトリ操作には、標準ライブラリの <code>std::fs</code> モジュールを使用する。<br> <br><br> == ディレクトリの作成 / 削除 == ==== ディレクトリの作成 ==== ディレクトリを新規作成する場合は、<code>std::fs::create_dir</code> メソッドを使用する。<br> <br> create_dirメソッドは、引数に指定したパスが示すディレクトリを新規作成する。<br> このメソッドは、Result型を返すため、エラーハンドリングが必要である。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/movie"; fs::create_dir(path)?; Ok(()) } </syntaxhighlight> <br> <u>※注意</u><br> <u>create_dirメソッドは、中間ディレクトリを作成することができない。</u><br> <u>例えば、/home/hoge/img/backディレクトリを作成する場合、/home/hoge/imgディレクトリが存在していない時は、エラーが発生する。</u><br> <u>また、新規作成するディレクトリが既に存在する場合も、エラーが発生する。</u><br> <br> ==== 中間ディレクトリも同時に作成する ==== 中間ディレクトリも同時に新規作成する場合、<code>std::fs::create_dir_all</code> メソッドを使用する。<br> <br> 引数に指定したパスが示すディレクトリを新規作成する。<br> 新規作成するディレクトリが既に存在する場合でも、エラーは発生しない。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/movie/back"; fs::create_dir_all(path)?; Ok(()) } </syntaxhighlight> <br> 以下の例では、./test/movie/backディレクトリを新規作成している。<br> ./test/movie/backディレクトリが存在しない場合でも、中間ディレクトリである./test/movieディレクトリを作成後、指定のパスのディレクトリが作成される。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() { let path = "./test/movie/back"; match fs::create_dir_all(path) { Ok(_) => println!("ディレクトリを作成しました: {}", path), Err(e) => eprintln!("エラー: {}", e), } } </syntaxhighlight> <br> ==== ディレクトリの削除 ==== ディレクトリを削除する場合は、<code>std::fs::remove_dir</code> メソッドを使用する。<br> <br> remove_dirメソッドは、引数に指定したパスが示すディレクトリを削除する。<br> <br> ただし、ディレクトリを削除する場合は、ディレクトリの中身が空である必要があることに注意する。<br> 削除するディレクトリが空ではない場合、エラーが発生する。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/doc"; fs::remove_dir(path)?; Ok(()) } </syntaxhighlight> <br> 存在しないディレクトリを削除する場合、エラーが発生する。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() { let path = "./test/doc"; match fs::remove_dir(path) { Ok(_) => println!("ディレクトリを削除しました: {}", path), Err(e) => eprintln!("エラー: {}", e), } } </syntaxhighlight> <br> ==== ディレクトリとディレクトリの中身の一括削除 ==== ディレクトリとディレクトリ内に存在するファイルを一括して削除する場合、<code>std::fs::remove_dir_all</code> メソッドを使用する。<br> <br> 引数に指定したパスが示すディレクトリを削除する。<br> ディレクトリ内にファイルやディレクトリが含まれている場合は、一括削除する。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/movie"; fs::remove_dir_all(path)?; Ok(()) } </syntaxhighlight> <br> 以下の例では、エラーハンドリングを行っている。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() { let path = "./test/movie"; match fs::remove_dir_all(path) { Ok(_) => println!("ディレクトリとその内容を削除しました: {}", path), Err(e) => eprintln!("エラー: {}", e), } } </syntaxhighlight> <br><br> == ディレクトリの存在確認 == 指定したパスが示すディレクトリが存在するかどうかを確認する場合、<code>std::path::Path</code> の <code>exists</code> メソッドを使用する。<br> <br> パスが存在する場合は、trueを返す。<br> また、existsメソッドは、引数に指定したパスがファイルまたはディレクトリであっても存在する場合は、trueを返すことに注意する。<br> <syntaxhighlight lang="rust"> use std::path::Path; fn main() { let path1 = Path::new("./test/address.txt"); if path1.exists() { println!("{}は存在します", path1.display()); } else { println!("{}は存在しません", path1.display()); } let path2 = Path::new("./test/user.txt"); if path2.exists() { println!("{}は存在します", path2.display()); } else { println!("{}は存在しません", path2.display()); } } </syntaxhighlight> <br> ディレクトリであることを確認するには、<code>is_dir</code> メソッドを併用する。<br> <syntaxhighlight lang="rust"> use std::path::Path; fn main() { let path = Path::new("./test"); if path.exists() && path.is_dir() { println!("{}はディレクトリとして存在します", path.display()); } } </syntaxhighlight> <br><br> == ディレクトリ名の変更 == ディレクトリ名を変更する場合は、<code>std::fs::rename</code> メソッドを使用する。<br> <br> 第1引数に指定したパスが示すディレクトリ名を、第2引数に指定したパスが示すディレクトリ名に変更する。<br> <br> ディレクトリ名を変更する場合、変更前と変更後でディレクトリの親ディレクトリが異なっていても問題ない。<br> ただし、ディレクトリ名を変更する時、変更後の親ディレクトリが存在しない場合、エラーが発生する。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let oldpath = "./test/book"; let newpath = "./test/memo"; fs::rename(oldpath, newpath)?; Ok(()) } </syntaxhighlight> <br> 以下の例では、エラーハンドリングを行っている。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() { let oldpath = "./test/book"; let newpath = "./test/memo"; match fs::rename(oldpath, newpath) { Ok(_) => println!("ディレクトリ名を変更しました: {} -> {}", oldpath, newpath), Err(e) => eprintln!("エラー: {}", e), } } </syntaxhighlight> <br> 変更後のパスが既に存在する場合の動作は、プラットフォームに依存する。<br> Windows環境の場合、変更後のパスが既に存在する場合、エラーが発生することがある。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() { let oldpath = "./test/book"; let newpath = "./back/memo"; // 既にmemoディレクトリが存在する場合は、エラーが発生する可能性がある match fs::rename(oldpath, newpath) { Ok(_) => println!("ディレクトリ名を変更しました"), Err(e) => eprintln!("エラー: {}", e), } } </syntaxhighlight> <br><br> == 条件に一致するディレクトリの一覧の取得 == ==== globクレートを使用したパターンマッチング ==== 指定した条件に一致するファイルやディレクトリの一覧を取得する場合は、<code>glob</code> クレートを使用する。<br> <br> globクレートは外部クレートであるため、Cargo.tomlファイルに以下の設定を追加する必要がある。<br> <syntaxhighlight lang="toml"> [dependencies] glob = "0.3" </syntaxhighlight> <br> globメソッドは、パスパターンとマッチするファイルおよびディレクトリを、イテレータとして取得する。<br> この時、パスには以下の特殊文字を指定することができる。<br> * <nowiki>*</nowiki> *: 0文字以上の任意の文字 * ? *: 1文字の任意の文字 * [abc] *: 括弧の中のいずれかの文字 <br> <nowiki>*</nowiki>は、0文字以上の任意の文字とマッチする。<br> 例えば、*.txtと指定する場合、a.txtやmemo.txt等の"0文字以上の任意の文字列" + ".txt"に一致するファイルおよびディレクトリの一覧を取得する。<br> <br> 以下の例では、./testディレクトリ内の全てのファイルおよびディレクトリの一覧を取得している。<br> <syntaxhighlight lang="rust"> use glob::glob; fn main() { for entry in glob("./test/*").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test/img ./test/movie ./test/pen.jpg </syntaxhighlight> <br> 以下の例では、bから始まるファイルおよびディレクトリの一覧を取得している。<br> <syntaxhighlight lang="rust"> use glob::glob; fn main() { for entry in glob("./test/b*").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test/back ./test/book.png </syntaxhighlight> <br> <code>?</code> は、1文字の任意の文字とマッチする。<br> 例えば、?.txtと指定する場合、a.txtやc.txt等の"1文字の任意の文字" + ".txt"と一致するファイルやディレクトリの一覧を取得する。<br> この時、2文字以上のabc.txt等にはマッチしない。<br> <br> 以下の例では、3文字の任意の文字で始まり、末尾が.txtのファイルおよびディレクトリの一覧を取得している。<br> <syntaxhighlight lang="rust"> use glob::glob; fn main() { for entry in glob("./test/???.txt").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test/cup.txt ./test/pen.txt </syntaxhighlight> <br> <code>[]</code> は、括弧の中に記述した文字のいずれか1文字とマッチする。<br> 例えば、199[789].txtと指定する場合、1997.txt、1998.txt、1999.txtと一致するファイルやディレクトリの一覧を取得する。<br> この時、1文字ではない19978.txt等にはマッチしない。<br> <br> また、[3-6] や [a-e] 等のようにハイフンを記述することにより、文字の範囲を指定することができる。<br> [3-6]は[3456]と等価、[a-e]は[abcde]と等価である。<br> <br> 以下の例では、最初にaからeまでの文字で始まり、末尾が.txtのファイルおよびディレクトリの一覧を取得している。<br> <syntaxhighlight lang="rust"> use glob::glob; fn main() { println!("a-eで始まる.txtファイル:"); for entry in glob("./test/[a-e]*.txt").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } println!("\nc-zで始まる.txtファイル:"); for entry in glob("./test/[c-z]*.txt").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test/book.txt ./test/environment.txt ./test/flavor.txt ./test/pen.txt </syntaxhighlight> <br> ==== 再帰的にディレクトリの一覧の取得 ==== パスの指定において、<code>**</code> を使用することにより、全てのファイルおよび0個以上のディレクトリとサブディレクトリにマッチする。<br> <br> 例えば、パスを./**/*.txtと指定する場合、a.txtやmemo.txt等の同階層のディレクトリにあるファイルの他に、<br> ./doc/b.txtや./html/back/2020/report.txt等のサブディレクトリにあるファイルも対象となる。<br> <br> 以下の例では、サブディレクトリを再帰的に検索して条件に一致するファイルを取得している。<br> <syntaxhighlight lang="rust"> use glob::glob; fn main() { for entry in glob("./test/**/*").expect("パターンの読み込みに失敗") { match entry { Ok(path) => println!("{}", path.display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test/img ./test/movie ./test/pen.txt ./test/back ./test/back/2020.txt </syntaxhighlight> <br><br> == ディレクトリに含まれるファイルとディレクトリの一覧の取得 == ==== ディレクトリの内容の取得 ==== 指定したディレクトリに含まれるファイルとディレクトリの一覧を取得する場合、<code>std::fs::read_dir</code> メソッドを使用する。<br> <br> 引数にディレクトリを指定する時、そのディレクトリに含まれるエントリ (ファイル または ディレクトリ) のイテレータを返す。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/"; let entries = fs::read_dir(path)?; for entry in entries { let entry = entry?; println!("{}", entry.path().display()); } Ok(()) } // 出力例 ./test/address.txt ./test/doc ./test/img ./test/name.txt </syntaxhighlight> <br> エントリから <code>file_name</code> メソッドを使用してファイル名のみを取得することもできる。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/"; let entries = fs::read_dir(path)?; for entry in entries { let entry = entry?; println!("{}", entry.file_name().to_string_lossy()); } Ok(()) } </syntaxhighlight> <br> ==== ファイルとディレクトリの判別 ==== 指定したパスにおいて、ファイルまたはディレクトリを判別する場合、<code>std::path::Path</code> の <code>is_file</code> メソッド および <code>is_dir</code> メソッドを使用する。<br> <br> is_fileメソッドは、パスが存在、かつ、ファイルの場合はtrueを返す。<br> is_dirメソッドは、パスが存在、かつ、ディレクトリの場合はtrueを返す。<br> <syntaxhighlight lang="rust"> use std::path::Path; fn main() { let path = Path::new("./test/"); println!("is_file: {}", path.is_file()); println!("is_dir: {}", path.is_dir()); let path2 = Path::new("./test/address.txt"); println!("is_file: {}", path2.is_file()); println!("is_dir: {}", path2.is_dir()); } // 出力 is_file: false is_dir: true is_file: true is_dir: false </syntaxhighlight> <br> 以下の例では、./testディレクトリに含まれるファイルとディレクトリの一覧を取得して、ファイルの場合は[F] + ファイル名、ディレクトリの場合は[D] + ディレクトリ名を出力している。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/"; let entries = fs::read_dir(path)?; for entry in entries { let entry = entry?; let path = entry.path(); let name = entry.file_name(); if path.is_file() { println!("[F]: {}", name.to_string_lossy()); } else { println!("[D]: {}", name.to_string_lossy()); } } Ok(()) } </syntaxhighlight> <br> ==== エントリに関する詳細情報の取得 ==== <code>read_dir</code> メソッドから得られる <code>DirEntry</code> オブジェクトには、<code>metadata</code> メソッドを使用してファイルやディレクトリに関する詳細情報を取得できる。<br> <br> metadataメソッドは、ファイルのサイズ、タイムスタンプ、パーミッション等の情報を含む <code>Metadata</code> オブジェクトを返す。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/"; let entries = fs::read_dir(path)?; for entry in entries { let entry = entry?; let metadata = entry.metadata()?; let name = entry.file_name(); if metadata.is_file() { println!("[F]: {} (サイズ: {} bytes)", name.to_string_lossy(), metadata.len()); } else { println!("[D]: {}", name.to_string_lossy()); } } Ok(()) } </syntaxhighlight> <br> 以下の例では、./testディレクトリに含まれるファイルとディレクトリの一覧を取得して、<br> ファイルの場合は[F] + ファイル名 + パス、ディレクトリの場合は[D] + ディレクトリ名 + パスを出力している。<br> <syntaxhighlight lang="rust"> use std::fs; fn main() -> std::io::Result<()> { let path = "./test/"; let entries = fs::read_dir(path)?; for entry in entries { let entry = entry?; let path = entry.path(); let name = entry.file_name(); let metadata = entry.metadata()?; if metadata.is_file() { println!("[F]: {} {}", name.to_string_lossy(), path.display()); } else { println!("[D]: {} {}", name.to_string_lossy(), path.display()); } } Ok(()) } </syntaxhighlight> <br><br> == 再帰的なディレクトリの走査 == ディレクトリを再帰的に走査する場合、<code>walkdir</code> クレートを使用すると便利である。<br> walkdirクレートは外部クレートなので、Cargo.tomlファイルに以下に示す設定を追加する必要がある。<br> <syntaxhighlight lang="toml"> [dependencies] walkdir = "2" </syntaxhighlight> <br> WalkDirは、指定したディレクトリとそのサブディレクトリを再帰的に走査するイテレータを提供する。<br> <syntaxhighlight lang="rust"> use walkdir::WalkDir; fn main() { for entry in WalkDir::new("./test") { match entry { Ok(entry) => println!("{}", entry.path().display()), Err(e) => eprintln!("エラー: {}", e), } } } // 出力例 ./test ./test/address.txt ./test/doc ./test/doc/memo.txt ./test/img ./test/img/photo.jpg </syntaxhighlight> <br> ディレクトリのみをフィルタリングすることもできる。<br> <syntaxhighlight lang="rust"> use walkdir::WalkDir; fn main() { for entry in WalkDir::new("./test") { match entry { Ok(entry) => { if entry.path().is_dir() { println!("[D]: {}", entry.path().display()); } } Err(e) => eprintln!("エラー: {}", e), } } } </syntaxhighlight> <br> <u>※注意</u><br> <u>エラーハンドリングは必須であり、Result型を適切に処理する必要がある。</u><br> <br> <u>パーミッション設定は、Unix系システムでは <code>std::os::unix::fs::PermissionsExt</code> トレイトを使用して行うことができる。</u><br> <br><br> __FORCETOC__ [[カテゴリ:Rust]]
Rustの基礎 - ディレクトリ
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse