名前空間
変種
操作

std::filesystem::copy

提供: cppreference.com
 
 
 
ヘッダ <filesystem> で定義
void copy(conststd::filesystem::path& from,

           conststd::filesystem::path& to );
void copy(conststd::filesystem::path& from,
           conststd::filesystem::path& to,

           std::error_code& ec );
(1) (C++17以上)
void copy(conststd::filesystem::path& from,

           conststd::filesystem::path& to,
           std::filesystem::copy_options options );
void copy(conststd::filesystem::path& from,
           conststd::filesystem::path& to,
           std::filesystem::copy_options options,

           std::error_code& ec );
(2) (C++17以上)

様々なオプションを使用して、ファイルおよびディレクトリをコピーします。

1) デフォルトの options として copy_options::none を使用した (2) と同等です。
2)options で表されるコピーオプションを使用して、ファイルまたはディレクトリ from をファイルまたはディレクトリ to にコピーします。

copy_options の任意のオプショングループ (copy_file グループであっても) の2つ以上のオプションが options に存在する場合、動作は未定義です。

動作は以下のようになります。

  • まず、他のことを行う前に、以下のいずれかを高々1回呼ぶことによって、 from の種別とパーミッションを取得します。
  • 必要であれば、以下のいずれかを高々1回呼ぶことによって、 to のステータスを取得します。
  • from または to のいずれかが処理系定義のファイル種別を持つ場合、この関数の効果は処理系定義です。
  • from が存在しなければ、エラーが報告されます。
  • fromto が同じファイルであれば、エラーが報告されます。 std::filesystem::equivalent によって判断されます。
  • from または to のいずれかが普通のファイルでなく、ディレクトリでもなく、シンボリックリンクでもない場合、エラーが報告されます。 std::filesystem::is_other によって判断されます。
  • from がディレクトリで to が普通のファイルの場合、エラーが報告されます。
  • from がシンボリックリンクの場合、
  • optionscopy_options::skip_symlink があれば、何もしません。
  • そうでなく、 to が存在せず、 optionscopy_options::copy_symlinks がある場合、 copy_symlink(from, to) のように動作します。
  • そうでなければ、エラーが報告されます。
  • そうでなく、 from が普通のファイルの場合、
  • optionscopy_options::directories_only があれば、何もしません。
  • そうでなく、 optionscopy_options::create_symlinks があれば、 to へのシンボリックリンクが作成されます。 ノート: to がカレントディレクトリにない場合、 from は絶対パスでなければなりません。
  • そうでなく、 optionscopy_options::create_hard_links があれば、 to へのハードリンクが作成されます。
  • そうでなく、 to がディレクトリであれば、 copy_file(from, to/from.filename(), options) のように動作します (ディレクトリ to 内に from のコピーをファイルとして作成します)。
  • そうでなければ、 copy_file(from, to, options) のように動作します (ファイルをコピーします)。
  • そうでなく、 from がディレクトリであり、 optionscopy_options::create_symlinks がセットされていれば、 std::make_error_code(std::errc::is_a_directory) に等しいエラーコードを持つエラーが報告されます。
  • そうでなく、 from がディレクトリで、 optionscopy_options::recursive があるか、 optionscopy_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 に設定されたとき他に何の効果も持たない、特別なビットです (このビットを設定する唯一の目的は、 optionscopy_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

[編集]関連項目

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