std::filesystem::copy
From cppreference.com
< cpp | filesystem
| ヘッダー <filesystem> で定義 |
||
| void copy( const std::filesystem::path& from, const std::filesystem::path& to ); |
(1) | (C++17以降) |
| void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(2) | (C++17以降) |
| void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(3) | (C++17以降) |
| void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(4) | (C++17以降) |
様々なオプションを使用して、ファイルやディレクトリをコピーします。
1,2) デフォルトは、options として
copy_options::none を使用した (3,4) と同等です。3,4) ファイルまたはディレクトリ from を、options で示されたコピーオプションを使用して、ファイルまたはディレクトリ to にコピーします。options に含まれる copy_options のオプショングループのいずれかに複数のオプションが存在する場合(
copy_file グループであっても)、動作は未定義です。動作は以下の通りです。
- まず、他の何よりも先に、options に
copy_options::skip_symlinks、copy_options::copy_symlinks、またはcopy_options::create_symlinksのいずれかが存在する場合、from のタイプとパーミッションを、std::filesystem::symlink_status を最大1回呼び出すことで取得します。
- std::filesystem::symlink_status, if
copy_options::skip_symlinks,copy_options::copy_symlinks, orcopy_options::create_symlinksis present in options; - std::filesystem::status otherwise.
- std::filesystem::symlink_status, if
- 必要に応じて、options に
copy_options::skip_symlinksまたはcopy_options::create_symlinksのいずれかが存在する場合、std::filesystem::symlink_status を最大1回呼び出すことで to のステータスを取得します。
- std::filesystem::symlink_status, if
copy_options::skip_symlinksorcopy_options::create_symlinksis present in options; - std::filesystem::status otherwise (including the case where
copy_options::copy_symlinksis present in options).
- std::filesystem::symlink_status, if
- from または to が実装定義の ファイルタイプ を持つ場合、この関数の影響は実装定義です。
- from が存在しない場合、エラーを報告します。
- from と to が std::filesystem::equivalent によって決定される同じファイルである場合、エラーを報告します。
- from または to が std::filesystem::is_other によって決定される通常のファイル、ディレクトリ、またはシンボリックリンクでない場合、エラーを報告します。
- from がディレクトリであり、to が通常のファイルである場合、エラーを報告します。
- If from is a symbolic link, then
- options に
copy_options::skip_symlinkが存在する場合、何も行いません。 - それ以外の場合で、to が存在せず、options に
copy_options::copy_symlinksが存在する場合、copy_symlink(from, to) が実行されたかのように動作します。 - それ以外の場合、エラーを報告します。
- options に
- それ以外の場合で、from が通常のファイルである場合、
- options に
copy_options::directories_onlyが存在する場合、何も行いません。 - それ以外の場合で、options に
copy_options::create_symlinksが存在する場合、to へのシンボリックリンクを作成します。注:from は絶対パスでなければなりません。ただし、to がカレントディレクトリにある場合を除きます。 - それ以外の場合で、options に
copy_options::create_hard_linksが存在する場合、to へのハードリンクを作成します。 - それ以外の場合で、to がディレクトリである場合、copy_file(from, to/from.filename(), options) が実行されたかのように動作します(from のコピーを to ディレクトリ内のファイルとして作成します)。
- それ以外の場合、copy_file(from, to, options) が実行されたかのように動作します(ファイルをコピーします)。
- options に
- それ以外の場合で、from がディレクトリであり、options に
copy_options::create_symlinksが設定されている場合、std::make_error_code(std::errc::is_a_directory) と等しいエラーコードでエラーを報告します。 - それ以外の場合で、from がディレクトリであり、options に
copy_options::recursiveが存在するか、または options が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 | - | ターゲットファイル、ディレクトリ、またはシンボリックリンクへのパス |
| エラーコード | - | 例外を投げないオーバーロードでのエラー報告のための出力パラメータ |
[編集] 戻り値
(なし)
[編集] 例外
noexcept とマークされていないオーバーロードは、メモリ割り当てが失敗した場合に std::bad_alloc をスローする可能性があります。
1,3) 基盤となるOS APIエラーが発生した場合、from を最初のパス引数、to を2番目のパス引数、OSエラーコードをエラーコード引数として構築された std::filesystem::filesystem_error をスローします。
2,4) OS API呼び出しが失敗した場合、OS APIのエラーコードを `std::error_code&` パラメータに設定し、エラーが発生しなかった場合は `ec.clear()` を実行します。
[編集] 注釈
ディレクトリをコピーする際のデフォルトの動作は、非再帰的なコピーです。ファイルはコピーされますが、サブディレクトリはコピーされません。
// Given // /dir1 contains /dir1/file1, /dir1/file2, /dir1/dir2 // and /dir1/dir2 contains /dir1/dir2/file3 // After std::filesystem::copy("/dir1", "/dir3"); // /dir3 is created (with the attributes of /dir1) // /dir1/file1 is copied to /dir3/file1 // /dir1/file2 is copied to /dir3/file2
copy_options::recursive を使用すると、サブディレクトリもその内容と共に再帰的にコピーされます。
// ...but after std::filesystem::copy("/dir1", "/dir3", std::filesystem::copy_options::recursive); // /dir3 is created (with the attributes of /dir1) // /dir1/file1 is copied to /dir3/file1 // /dir1/file2 is copied to /dir3/file2 // /dir3/dir2 is created (with the attributes of /dir1/dir2) // /dir1/dir2/file3 is copied to /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"); // copy file fs::copy("sandbox/dir", "sandbox/dir2"); // copy directory (non-recursive) 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) |
コピー操作のセマンティクスを指定する (列挙型) |
| (C++17) |
シンボリックリンクをコピーする (関数) |
| (C++17) |
ファイルの内容をコピーする (関数) |