【C++17】filesystemでファイルやディレクトリをコピーする方法

目次

はじめに

C++で、ファイルのバックアップを作成したり、ディレクトリ構造を丸ごと複製したりしたい場合があります。

C++17で導入された <filesystem> ライブラリは、このファイルシステムのコピー操作を、OSに依存しない移植性の高いコードで簡単に行うための関数を提供しています。

  1. std::filesystem::copy_file: 単一のファイルをコピーする。
  2. 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_filecopy は、第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++のコード内で完結した、移植性の高いファイル操作が可能になります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次