std::filesystem::copy
ヘッダ <filesystem> で定義 | ||
void copy(conststd::filesystem::path& from, conststd::filesystem::path& to ); | (1) | (C++17以上) |
void copy(conststd::filesystem::path& from, conststd::filesystem::path& to, | (2) | (C++17以上) |
様々なオプションを使用して、ファイルおよびディレクトリをコピーします。
options
として copy_options::none
を使用した (2) と同等です。options
で表されるコピーオプションを使用して、ファイルまたはディレクトリ from
をファイルまたはディレクトリ to
にコピーします。 copy_options の任意のオプショングループ (copy_file
グループであっても) の2つ以上のオプションが options
に存在する場合、動作は未定義です。
動作は以下のようになります。
- まず、他のことを行う前に、以下のいずれかを高々1回呼ぶことによって、
from
の種別とパーミッションを取得します。
options
にcopy_options::skip_symlinks
、copy_options::copy_symlinks
、またはcopy_options::create_symlinks
があれば、 std::filesystem::symlink_status。- そうでなければ、 std::filesystem::status。
- 必要であれば、以下のいずれかを高々1回呼ぶことによって、
to
のステータスを取得します。
options
にcopy_options::skip_symlinks
またはcopy_options::create_symlinks
があれば、 std::filesystem::symlink_status。- そうでなければ (
options
にcopy_options::copy_symlinks
が指定されている場合も含む) std::filesystem::status。
from
またはto
のいずれかが処理系定義のファイル種別を持つ場合、この関数の効果は処理系定義です。from
が存在しなければ、エラーが報告されます。from
とto
が同じファイルであれば、エラーが報告されます。 std::filesystem::equivalent によって判断されます。from
またはto
のいずれかが普通のファイルでなく、ディレクトリでもなく、シンボリックリンクでもない場合、エラーが報告されます。 std::filesystem::is_other によって判断されます。from
がディレクトリでto
が普通のファイルの場合、エラーが報告されます。from
がシンボリックリンクの場合、
options
にcopy_options::skip_symlink
があれば、何もしません。- そうでなく、
to
が存在せず、options
にcopy_options::copy_symlinks
がある場合、 copy_symlink(from, to) のように動作します。 - そうでなければ、エラーが報告されます。
- そうでなく、
from
が普通のファイルの場合、
options
にcopy_options::directories_only
があれば、何もしません。- そうでなく、
options
にcopy_options::create_symlinks
があれば、to
へのシンボリックリンクが作成されます。 ノート:to
がカレントディレクトリにない場合、from
は絶対パスでなければなりません。 - そうでなく、
options
にcopy_options::create_hard_links
があれば、to
へのハードリンクが作成されます。 - そうでなく、
to
がディレクトリであれば、 copy_file(from, to/from.filename(), options) のように動作します (ディレクトリto
内にfrom
のコピーをファイルとして作成します)。 - そうでなければ、 copy_file(from, to, 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
がすでに存在していたか今作成されたところかによらず、 for(conststd::filesystem::directory_entry& x :std::filesystem::directory_iterator(from)) によって行われたかのようにfrom
に含まれるファイルをイテレートし、それぞれのディレクトリエントリについて、再帰的に copy(x.path(), to/x.path().filename(), options | in-recursive-copy) を呼びます。 ただし in-recursive-copy は、options
に設定されたとき他に何の効果も持たない、特別なビットです (このビットを設定する唯一の目的は、options
がcopy_options::none
の場合にサブディレクトリの再帰コピーを防ぐことです)。
- そうでなければ、何もしません。
目次 |
[編集]引数
from | - | コピー元のファイル、ディレクトリ、またはシンボリックリンクを指すパス |
to | - | コピー先のファイル、ディレクトリ、またはシンボリックリンクを指すパス |
ec | - | 例外を投げないオーバーロードでエラーを報告するための出力引数 |
[編集]戻り値
(なし)
[編集]例外
std::error_code& 引数を取らないオーバーロードは、ベースとなる OS の API でエラーが発生した場合、第1パス引数に from
、第2パス引数に to
、エラーコード引数に OS のエラーコードを指定して構築された filesystem_error を投げます。 std::error_code& 引数を取るオーバーロードは、 OS の API 呼び出しが失敗した場合、その引数を OS の API のエラーコードに設定し、エラーが発生しない場合は ec.clear() を実行します。 noexcept
指定のないあらゆるオーバーロードは、メモリ確保に失敗した場合 std::bad_alloc を投げる可能性があります。
[編集]ノート
ディレクトリをコピーするときのデフォルトの動作は、非再帰コピーです。 ファイルはコピーされますが、サブディレクトリはコピーされません。
// 実行前、// /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 <iostream>#include <fstream>#include <filesystem>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");// ディレクトリをコピーします (再帰しません)。constauto 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 overload marked noexcept but can allocate memory | noexcept removed |
LWG 2682 | C++17 | attempting to create a symlink for a directory succeeds but does nothing | reports an error |
[編集]関連項目
(C++17) | コピー操作のセマンティクスを指定します (列挙) |
(C++17) | シンボリックリンクをコピーします (関数) |
(C++17) | ファイルの内容をコピーします (関数) |