名前空間
変種
操作

std::filesystem::copy

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

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

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

           const std::filesystem::path& to,
           std::filesystem::copy_options options );
void copy( const std::filesystem::path& from,
           const std::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 (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 に設定されたとき他に何の効果も持たない、特別なビットです (このビットを設定する唯一の目的は、 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"); // ディレクトリをコピーします (再帰しません)。
    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

[編集] 関連項目

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