ファイル/ディレクトリ操作には、Boost Filesystem Libraryを使用する。Boost Filesystem Libraryは、多くのプラットフォーム、コンパイラで動作する汎用的なファイル/ディレクトリ操作のライブラリである。このライブラリはビルドを必要する。
インデックス
- エラーハンドリング
- ファイルをコピーする
- ファイルの削除
- ファイルを移動する/ファイル名を変更する
- ファイルが存在するかを調べる
- ファイルサイズを取得する
- ファイルの最終更新日時を取得する
- パスのファイル名を取得する
- パスの拡張子を取得する
- パスの拡張子を変更する
- ディレクトリを作成する
- ディレクトリ内のファイルを列挙する
- ディレクトリ内の全てのファイルを再帰的に列挙
エラーハンドリング
Boost Filesystem Libraryのエラーハンドリングは、例外を投げるバージョン、エラーを参照で返すバージョンの2種類が存在する。
例外バージョン
何も指定しなければ、Boost Filesystem Libraryの関数でエラーが出た場合にはboost::filesystem::filesystem_error
例外が投げられる。
namespace fs = boost::filesystem; try { fs::foo(); } catch (fs::filesystem_error& ex) { std::cout << "エラー発生! : " << ex.what() << std::endl; }
エラーを参照で返すバージョン
Boost Filesystem Libraryの最後の引数として、boost::system::error_code
の変数を渡せば、例外ではなく渡したエラー用変数にエラー情報が格納される。
namespace fs = boost::filesystem; boost::system::error_code error; fs::foo(error); if (error) { std::cout << "エラー発生! : " << error.message() << std::endl; }
ファイルをコピーする
ファイルをコピーするには、boost::filesystem::copy_file()
関数を使用する。
- 第1引数はコピー元のパス
- 第2引数はコピー先のパス
コピーに失敗した場合は例外が投げられる。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); // コピー元 const fs::path dest("dir2/a.txt"); // コピー先 try { fs::copy_file(path, dest); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
上書きコピーをする場合は、copy_file()
関数に、boost::filesystem::copy_option::overwrite_if_exists
オプションを指定する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); const fs::path dest("dir2/a.txt"); try { fs::copy_file(path, dest, fs::copy_option::overwrite_if_exists); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
ファイルを削除する
ファイルを削除するには、boost::filesystem::remove()
を使用する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); try { fs::remove(path); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
ファイルを移動する/ファイル名を変更する
ファイルの移動、ファイル名の変更には、boost::filesystem::rename()
を使用する。
- 第1引数は、元となるファイルのパス。
- 第2引数は、移動先のファイルパス、もしくは新たなファイル名。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); const fs::path dest("dir2/b.txt"); try { fs::rename(path, dest); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
ファイルが存在するかを調べる
ファイルが存在するか調べるには、boost::filesystem::exists()
関数を使用する。
この関数は、ファイルが存在する場合はtrue
を返し、存在しない場合はfalse
を返す。
ファイルのステータス取得に失敗した場合はエラーを返す。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); boost::system::error_code error; const bool result = fs::exists(path, error); if (!result || error) { std::cout << "ファイルがない" << std::endl; } else { std::cout << "ファイルがあった" << std::endl; } }
ファイルサイズを取得する
ファイルサイズを取得するには、boost::filesystem::file_size()
関数を使用する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/a.txt"); try { const boost::uintmax_t size = fs::file_size(path); std::cout << "ファイルサイズ: " << size << std::endl; } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
実行結果の例:
ファイルサイズ: 5107200
ファイルの最終更新日時を取得する
ファイルの最終更新日時を取得するには、boost::filesystem::last_write_time()
関数を使用する。
この関数は戻り値として、std::time_t
型として日時を返す。
#include <iostream> #include <boost/filesystem.hpp> #include <boost/date_time/posix_time/posix_time.hpp> namespace fs = boost::filesystem; int main() { try { const fs::path path("dir1/a.txt"); const std::time_t last_update = fs::last_write_time(path); const boost::posix_time::ptime time = boost::posix_time::from_time_t(last_update); std::cout << time << std::endl; } catch (fs::filesystem_error& ex) { std::cout << "エラー発生! : " << ex.what() << std::endl; } }
実行結果の例:
2011-Mar-30 05:56:11
パスのファイル名を取得する
パスのファイル名を取得するには、boost::filesystem::path
クラスのfilename()
メンバ関数を使用する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { fs::path p = "/a/b.txt"; fs::path filename = p.filename(); std::cout << filename.generic_string() << std::endl; }
出力:
b.txt
パスの拡張子を取得する
パスの拡張子を取得するには、boost::filesystem::path
クラスのextension()
メンバ関数を使用する。この関数が返すパスは、ドット(.)を含む。
拡張子を持たないパスに対してこの関数を適用した場合は、空のパスが返る。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { fs::path p = "/a/b.txt"; fs::path extension = p.extension(); std::cout << extension.generic_string() << std::endl; }
出力:
.txt
パスの拡張子を変更する
パスの拡張子を変更するには、boost::filesystem::path
クラスのreplace_extension()
メンバ関数を使用する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { // 拡張子を.pngに変更する // replace_extension()に指定する拡張子は、 // ドット(.)があってもなくても、どちらでもよい。 fs::path p = "/a.txt/b.txt"; p.replace_extension("png"); std::cout << p.generic_string() << std::endl; }
出力:
/a.txt/b.png
ディレクトリを作成する
ディレクトリを作成するには、boost::filesystem::create_directory()
関数を使用する。
第1引数として、ディレクトリのパスを指定する。
ネストしたディレクトリを一度に作ろうとした場合はエラーとなる。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir"); boost::system::error_code error; const bool result = fs::create_directory(path, error); if (!result || error) { std::cout << "ディレクトリの作成に失敗" << std::endl; } }
ネストしたディレクトリを含めて一度に作成するには、boost::filesystem::create_directories()
関数を使用する。
#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1/dir2"); boost::system::error_code error; const bool result = fs::create_directories(path, error); if (!result || error) { std::cout << "ディレクトリの作成に失敗" << std::endl; } }
ディレクトリ内のファイルを列挙する
ディレクトリ内のファイルを列挙するには、boost::filesystem::directory_iterator
クラスを使用する。
#include <iostream> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("dir1"); BOOST_FOREACH(const fs::path& p, std::make_pair(fs::directory_iterator(path), fs::directory_iterator())) { if (!fs::is_directory(p)) std::cout << p.filename() << std::endl; } }
実行結果の例
"a.txt"
"b.png"
あるいは、上記の実装例の BOOST_FOREACH
部分は C++11 以降で range-based-for を使いたい場合、次のようにも書ける。
#include <iostream> #include <boost/filesystem.hpp> #include <boost/range/iterator_range.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("."); // この例の場合、 e は fs::path 型ではなく fs::directory_entry 型となる点に注意する。 for ( const auto& e : boost::make_iterator_range( fs::directory_iterator( path ), { } ) ) if ( ! fs::is_directory( e ) ) std::cout << e.path().filename() << std::endl; }
実行結果の例は先の BOOST_FOREACH
バージョンと同様となるので省略する。
ディレクトリ内の全てのファイルを再帰的に列挙する
ディレクトリ内の全てのファイルを再帰的に列挙するには、boost::filesystem::recursive_directory_iterator
クラスを使用する。
#include <iostream> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> namespace fs = boost::filesystem; int main() { const fs::path path("D:/boost_1_49_0/boost/filesystem"); BOOST_FOREACH(const fs::path& p, std::make_pair(fs::recursive_directory_iterator(path), fs::recursive_directory_iterator())) { if (!fs::is_directory(p)) std::cout << p << std::endl; } }
実行結果の例
"D:/boost_1_49_0/boost/filesystem\config.hpp"
"D:/boost_1_49_0/boost/filesystem\convenience.hpp"
"D:/boost_1_49_0/boost/filesystem\detail\utf8_codecvt_facet.hpp"
"D:/boost_1_49_0/boost/filesystem\exception.hpp"
"D:/boost_1_49_0/boost/filesystem\fstream.hpp"
"D:/boost_1_49_0/boost/filesystem\operations.hpp"
"D:/boost_1_49_0/boost/filesystem\path.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\config.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\convenience.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\exception.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\fstream.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\operations.hpp"
"D:/boost_1_49_0/boost/filesystem\v2\path.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\config.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\convenience.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\exception.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\fstream.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\operations.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\path.hpp"
"D:/boost_1_49_0/boost/filesystem\v3\path_traits.hpp"