第63回 std::filesystem

ファイル・ディレクトリ操作のクロスプラットフォームな標準 API。C 時代の stat, opendir, POSIX 依存コードから解放されます。C++17 で標準化(それ以前は Boost.Filesystem)。

1. 主要機能

機能関数
パス操作fs::path
存在確認fs::exists
種別判定is_regular_file, is_directory, is_symlink
ファイルサイズfs::file_size
ディレクトリ作成create_directory, create_directories
削除remove, remove_all
コピー/名前変更copy, rename
走査directory_iterator, recursive_directory_iterator
カレントcurrent_path, temp_directory_path

2. path クラス

path基本
#include <filesystem> namespace fs = std::filesystem; fs::path p = "/home/user/data.txt"; p.filename(); // "data.txt" p.extension(); // ".txt" p.stem(); // "data" p.parent_path(); // "/home/user" // パスの連結(/ 演算子) fs::path dir = "/home/user"; fs::path full = dir / "data.txt"; // OS に応じた区切り文字 // 文字列化 std::string s = full.string();

3. 存在確認・操作

典型操作filesystem
if (fs::exists(p)) { if (fs::is_regular_file(p)) { auto sz = fs::file_size(p); std::cout << sz << " bytes\n"; } } // ディレクトリ作成 fs::create_directories("/tmp/a/b/c"); // 再帰的に作る // コピー fs::copy("src.txt", "dst.txt"); fs::copy("srcdir", "dstdir", fs::copy_options::recursive); // 削除 fs::remove("file.txt"); fs::remove_all("dir"); // 中身ごと再帰削除

4. ディレクトリ走査

直下のみdirectory_iterator
for (auto& entry : fs::directory_iterator("/path")) { std::cout << entry.path() << "\n"; if (entry.is_regular_file()) { std::cout << " size=" << entry.file_size(); } }
再帰recursive_directory_iterator
for (auto& e : fs::recursive_directory_iterator("/path")) { std::cout << e.path() << "\n"; } // 全サブディレクトリを走査

5. 旧 API からの移行

  • stat()fs::exists / fs::file_size
  • mkdir()fs::create_directory
  • rmdir() / unlink()fs::remove
  • opendir/readdirfs::directory_iterator
  • getcwd()fs::current_path()

Windows / Linux / macOS の違いを吸収してくれます。POSIX/Win32 API を直接叩く必要はほぼなくなりました。

確認クイズ

Q1. std::filesystem が標準化された C++ のバージョンは?

C++11
C++14
C++17
C++20
C++17 で標準化。それ以前は Boost.Filesystem として同等の API が提供されていました。

Q2. fs::path p = "/a/b"; p / "c" の結果は?

"/a/b c"
"/a/b/c"
コンパイルエラー
例外
/ 演算子でパスを OS ネイティブの区切り文字で連結できます。

Q3. ディレクトリを中身ごと削除する関数は?

fs::remove
fs::delete_directory
fs::remove_all
fs::rm_rf
remove は単一ファイル(または空ディレクトリ)、remove_all は再帰的に削除。

Q4. サブディレクトリも含めて全ファイルを走査するには?

directory_iterator
recursive_directory_iterator
iterate_dir
walk
recursive 版を使うとサブディレクトリも自動で展開されます。