Namespaces
Variants

std::filesystem:: copy

From ja.cppreference.net
ヘッダーで定義 <filesystem>
void copy ( const std:: filesystem :: path & from,
const std:: filesystem :: path & to ) ;
(1) (C++17以降)
(2) (C++17以降)
(3) (C++17以降)
(4) (C++17以降)

ファイルとディレクトリを様々なオプションでコピーします。

1,2) デフォルト、 (3,4) と同等で、 copy_options::none が options として使用される。
3,4) ファイルまたはディレクトリを from からファイルまたはディレクトリ to へコピーします。 options で指定されたコピーオプションを使用します。 copy_options のオプショングループ内に複数のオプションが存在する場合( copy_file グループ内であっても)、動作は未定義です。

動作は以下の通りです:

  • まず最初に、他の何よりも先に、最大1回の呼び出しで from の型と権限を取得します
  • 必要に応じて、 to のステータスを、最大1回の呼び出しで取得します
  • from または to のいずれかが実装定義の file type を持つ場合、この関数の効果は実装定義である。
  • from が存在しない場合、エラーを報告する。
  • from と to が std::filesystem::equivalent によって判定された同じファイルである場合、エラーを報告する。
  • from または to のいずれかが std::filesystem::is_other によって判定された通常ファイル、ディレクトリ、またはシンボリックリンクでない場合、エラーを報告する。
  • from がディレクトリであり、かつ to が通常ファイルである場合、エラーを報告する。
  • from がシンボリックリンクである場合、
  • copy_options::skip_symlink が options に含まれている場合、何も行わない。
  • それ以外の場合、 to が存在せず、かつ copy_options::copy_symlinks が options に含まれている場合、 copy_symlink ( from, to ) のように動作する。
  • それ以外の場合、エラーを報告する。
  • それ以外の場合、 from が通常ファイルであれば、
  • copy_options::directories_only が options に含まれている場合、何も行わない。
  • そうでなく、copy_options::create_symlinks が options に含まれている場合、to へのシンボリックリンクを作成する。注記: to がカレントディレクトリ内にない限り、from は絶対パスでなければならない。
  • そうでなく、copy_options::create_hard_links が options に含まれている場合、to へのハードリンクを作成する。
  • そうでなく、to がディレクトリである場合、copy_file(from, to/from.filename(), options) を実行した場合と同様に振る舞う(from のコピーをディレクトリ to 内のファイルとして作成する)。
  • それ以外の場合、copy_file(from, to, options) を実行した場合と同様に振る舞う(ファイルをコピーする)。
  • それ以外の場合、 from がディレクトリであり、かつ copy_options::create_symlinks が options に設定されている場合、 std:: make_error_code ( std:: errc :: is_a_directory ) と等しいエラーコードでエラーを報告する。
  • それ以外の場合、 from がディレクトリであり、かつ options が copy_options::recursive を含むか、または copy_options::none である場合、
  • to が存在しない場合、最初に create_directory ( to, from ) を実行する(古いディレクトリの属性をコピーして新しいディレクトリを作成)。
  • 次に、 to が既に存在していたか、新しく作成されたかに関わらず、 from に含まれるファイルを for ( const std:: filesystem :: directory_entry & x : std:: filesystem :: directory_iterator ( from ) ) によって反復処理し、各ディレクトリエントリに対して copy ( x. path ( ) , to / x. path ( ) . filename ( ) , options | in - recursive - copy ) を再帰的に呼び出す。ここで in-recursive-copy は、 options で設定された場合に他の効果を持たない特別なビットである。(このビットを設定する唯一の目的は、 options が copy_options::none の場合にサブディレクトリの再帰的コピーを防ぐことである。)
  • それ以外の場合は何もしません。

目次

パラメータ

from - ソースファイル、ディレクトリ、またはシンボリックリンクへのパス
to - ターゲットファイル、ディレクトリ、またはシンボリックリンクへのパス
ec - 非スローオーバーロードでのエラー報告用出力パラメータ

戻り値

(なし)

例外

noexcept でマークされていないオーバーロードは、 メモリ確保に失敗した場合 std::bad_alloc をスローする可能性があります。

1,3) 基盤となるOS APIエラーが発生した場合 std::filesystem::filesystem_error をスローします。この例外は、 from を第1パス引数、 to を第2パス引数、OSエラーコードをエラーコード引数として構築されます。
2,4) 設定する std:: error_code & パラメータをOS APIエラーコードに(OS API呼び出しが失敗した場合)、そして実行する ec. clear ( ) (エラーが発生しなかった場合)。

注記

ディレクトリをコピーする際のデフォルトの動作は非再帰的コピーです:ファイルはコピーされますが、サブディレクトリはコピーされません:

// 前提条件
// /dir1 は /dir1/file1, /dir1/file2, /dir1/dir2 を含む
// また /dir1/dir2 は /dir1/dir2/file3 を含む
// 実行後
std::filesystem::copy("/dir1", "/dir3");
// /dir3 が作成される (/dir1 の属性と共に)
// /dir1/file1 は /dir3/file1 にコピーされる
// /dir1/file2 は /dir3/file2 にコピーされる

copy_options::recursiveを使用すると、サブディレクトリもその内容と共に再帰的にコピーされます。

// ...ただしその後
std::filesystem::copy("/dir1", "/dir3", std::filesystem::copy_options::recursive);
// /dir3が作成される (/dir1の属性付き)
// /dir1/file1が/dir3/file1にコピーされる
// /dir1/file2が/dir3/file2にコピーされる
// /dir3/dir2が作成される (/dir1/dir2の属性付き)
// /dir1/dir2/file3が/dir3/dir2/file3にコピーされる

例

#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
int main()
{
    fs::create_directories("sandbox/dir/subdir");
    std::ofstream("sandbox/file1.txt").put('a');
    fs::copy("sandbox/file1.txt", "sandbox/file2.txt"); // ファイルをコピー
    fs::copy("sandbox/dir", "sandbox/dir2"); // ディレクトリをコピー(非再帰的)
    const auto copyOptions = fs::copy_options::update_existing
                           | fs::copy_options::recursive
                           | fs::copy_options::directories_only
                           ;
    fs::copy("sandbox", "sandbox_copy", copyOptions); 
    static_cast<void>(std::system("tree"));
    fs::remove_all("sandbox");
    fs::remove_all("sandbox_copy");
}

出力例:

.
├── sandbox
│   ├── dir
│   │   └── subdir
│   ├── dir2
│   ├── file1.txt
│   └── file2.txt
└── sandbox_copy
    ├── dir
    │   └── subdir
    └── dir2
8 directories, 2 files

不具合報告

以下の動作変更欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 3013 C++17 error_code オーバーロードがnoexcept指定されているがメモリを確保する可能性がある noexceptを削除
LWG 2682 C++17 ディレクトリのシンボリックリンクを作成しようとすると成功するが何も行わない エラーを報告する

関連項目

コピー操作のセマンティクスを指定する
(列挙型)
シンボリックリンクをコピーする
(関数)
(C++17)
ファイル内容をコピーする
(関数)