はじめに
C++で、ファイルのバックアップを作成したり、ディレクトリ構造を丸ごと複製したりしたい場合があります。
C++17で導入された <filesystem>
ライブラリは、このファイルシステムのコピー操作を、OSに依存しない移植性の高いコードで簡単に行うための関数を提供しています。
std::filesystem::copy_file
: 単一のファイルをコピーする。std::filesystem::copy
: ファイル、またはディレクトリ(とその中身)をコピーする。
この記事では、これら2つの関数の使い方と、コピー時の動作を制御するコピーオプションについて解説します。
【前提】C++17とは?
C++17は、2017年に正式化されたC++言語の規格です。<filesystem>
ライブラリはこのC++17で導入されたため、利用するにはC++17に対応したコンパイラと、適切なコンパイラ設定(および、一部の環境ではリンカ設定)が必要になります。
ファイル・ディレクトリをコピーするサンプルコード
1. copy_file
: 単一のファイルをコピーする
copy_file
は、一つのファイルを別の場所にコピーします。ディレクトリのコピーはできません。
#include <iostream>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
int main() {
fs::path source_file = "source.txt";
fs::path destination_file = "destination.txt";
// テスト用のソースファイルを作成
std::ofstream(source_file) << "hello";
// ファイルをコピー
fs::copy_file(source_file, destination_file);
if (fs::exists(destination_file)) {
std::cout << "copy_file: ファイルのコピーに成功しました。" << std::endl;
}
// 後片付け
fs::remove(source_file);
fs::remove(destination_file);
return 0;
}
2. copy
: ディレクトリを再帰的にコピーする
copy
は、ファイルだけでなく、ディレクトリもコピーできます。copy_options::recursive
を指定すると、ディレクトリの中身も丸ごと再帰的にコピーします。
#include <iostream>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
int main() {
fs::path source_dir = "source_folder";
fs::path dest_dir = "destination_folder";
// テスト用のディレクトリとファイルを作成
fs::create_directories(source_dir / "sub");
std::ofstream(source_dir / "file1.txt");
std::ofstream(source_dir / "sub" / "file2.txt");
// ディレクトリを再帰的にコピー
fs::copy(source_dir, dest_dir, fs::copy_options::recursive);
if (fs::exists(dest_dir / "sub" / "file2.txt")) {
std::cout << "copy: ディレクトリの再帰的なコピーに成功しました。" << std::endl;
}
// 後片付け
fs::remove_all(source_dir);
fs::remove_all(dest_dir);
return 0;
}
copy_options
: コピー動作の制御
copy_file
と copy
は、第3引数に copy_options
を指定することで、コピー先にファイルが既に存在する場合などの動作を細かく制御できます。
copy_options | 説明 |
none | デフォルト。コピー先にファイルが存在するとエラー。 |
overwrite_existing | コピー先にファイルが存在する場合、上書きする。 |
update_existing | コピー先のファイルが、コピー元のファイルより古い場合のみ上書きする。 |
skip_existing | コピー先にファイルが存在する場合、そのファイルのコピーをスキップする。 |
recursive | (copy 専用) ディレクトリを再帰的にコピーする。 |
複数のオプションは |
(ビットOR演算子) で組み合わせることができます。 fs::copy_options::recursive | fs::copy_options::overwrite_existing
まとめ
今回は、C++17の <filesystem>
ライブラリを使って、ファイルやディレクトリをコピーする方法を解説しました。
copy_file()
: 単一のファイルをコピーする。copy()
: ファイルまたはディレクトリをコピーする。copy_options
: 上書きや再帰コピーといった動作を制御する。
これらの関数を使うことで、OSのコピーコマンドを呼び出す必要なく、C++のコード内で完結した、移植性の高いファイル操作が可能になります。