filesystemの概要
filesystemはBoostに収録されたライブラリ:boost.filesystemをベースとし、今年末までには決まるはずの標準規格:C++17の一部となる予定。まだ仕様が確定していないので、Visual C++ 2015/2017に見つけたfilesystemは実験的(experimental)な実装であり、クラスや関数は名前空間:std::experimental::filesystemに置かれています。
filesystemのイケてるところをお見せするため、「カレント・ディレクトリ配下のファイル/ディレクトリを再帰的に列挙する」コードを書きました。
まずはWin32-API版。
#undef UNICODE
#include <Windows.h>
#include <iostream>
#include <string>
void walk_dir_recursive(const std::string& dir) {
WIN32_FIND_DATA data;
// 最初のエントリを探す(結果はdataに格納される)
HANDLE handle = FindFirstFile((dir + "\\*.*").c_str(), &data);
while ( handle != INVALID_HANDLE_VALUE ) {
std::string filename = data.cFileName;
if (filename != "." && filename != "..") { // . と .. は除外して
filename = dir + "\\" + filename;
// そのエントリがディレクトリなら
if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
std::cout << "dir. " << filename << std::endl;
walk_dir_recursive(filename); // さらに深く潜る
} else {
std::cout << "file " << filename << std::endl;
}
}
// 次のエントリを探す。なかったらCloseしてwhile-loopを抜ける。
if ( !FindNextFile(handle, &data) ) {
FindClose(handle);
handle = INVALID_HANDLE_VALUE;
}
}
}
int main() {
// カレント・ディレクトリから列挙開始
char current[260];
GetCurrentDirectory(260, current);
walk_dir_recursive(current);
}
FindFirstFile()でエントリの最初の一つを手に入れ、次のエントリを取り出すFindNextFile()を繰り返し、FindClose()で終了。取り出したエントリがディレクトリなら再帰的に呼び出してます、そこそこメンド臭いですね。こんな実行結果が得られます。

かたやfilesystemを使うと:
#include <filesystem>
#include <iostream>
namespace fs = std::experimental::filesystem;
void walk_dir_recursive(const fs::path& dir) {
for ( auto ent : fs::recursive_directory_iterator(dir) ) {
std::cout << (fs::is_directory(ent) ? "dir. " : "file ")
<< ent << std::endl;
}
}
int main() {
// カレント・ディレクトリから列挙開始
walk_dir_recursive(fs::current_path());
}
たったこれだけでWin32版と同じ結果が得られます。
