std::filesystem::copy - cppreference.com
提供: cppreference.com
<tbody> </tbody>
| ヘッダ |
||
|
|
(1) | (C++17以上) |
|
|
(2) | (C++17以上) |
様々なオプションを使用して、ファイルおよびディレクトリをコピーします。
1) デフォルトの options として copy_options::none を使用した (2) と同等です。
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 (const std::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"); // ディレクトリをコピーします (再帰しません)。 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 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 |