# std::filesystem::copy

From cppreference.com
< cpp‎ | filesystem

Defined in header `<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) | (since 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) | (since C++17)

Copies files and directories, with a variety of options

1) The default, equivalent to (2) with `copy_options::none` used as `options`
2) Copies the file or directory `from` to file or directory `to`, using the copy options indicated by `options`. The behavior is undefined if there is more than one option in any of the copy_options option group present in `options` (even in the `copy_file` group).

The behavior is as follows:

- First, before doing anything else, obtains type and permissions of `from` by no more than a single call to

  - std::filesystem::symlink_status, if `copy_options::skip_symlinks`, `copy_options::copy_symlinks`, or `copy_options::create_symlinks` is present in `options`;
  - std::filesystem::status otherwise.

- If necessary, obtains the status of `to`, by no more than a single call to

  - std::filesystem::symlink_status, if `copy_options::skip_symlinks` or `copy_options::create_symlinks` is present in `options`;
  - std::filesystem::status otherwise (including the case where `copy_options::copy_symlinks` is present in `options`).

- If either `from` or `to` has an implementation-defined file type, the effects of this function are implementation-defined.
- If `from` does not exist, reports an error.
- If `from` and `to` are the same file as determined by std::filesystem::equivalent, reports an error
- If either `from` or `to` is not a regular file, a directory, or a symlink, as determined by std::filesystem::is_other, reports an error
- If `from` is a directory, but `to` is a regular file, reports an error
- If `from` is a symbolic link, then

  - If `copy_options::skip_symlink` is present in `options`, does nothing.
  - Otherwise, if `to` does not exist and `copy_options::copy_symlinks` is present in `options`, then behaves as if copy_symlink(from, to)
  - Otherwise, reports an error

- Otherwise, if `from` is a regular file, then

  - If `copy_options::directories_only` is present in `options`, does nothing
  - Otherwise, if `copy_options::create_symlinks` is present in `options`, creates a symlink to `to`. Note: `from` must be an absolute path unless `to` is in the current directory.
  - Otherwise, if `copy_options::create_hard_links` is present in `options`, creates a hard link to `to`
  - Otherwise, if `to` is a directory, then behaves as if copy_file(from, to/from.filename(), options) (creates a copy of `from` as a file in the directory `to`)
  - Otherwise, behaves as if copy_file(from, to, options) (copies the file)

- Otherwise, if `from` is a directory and `copy_options::create_symlinks` is set in `options`, reports an error with an error code equal to std::make_error_code(std::errc::is_a_directory).
- Otherwise, if `from` is a directory and either `options` has `copy_options::recursive` or is `copy_options::none`,

  - If `to` does not exist, first executes create_directory(to, from) (creates the new directory with a copy of the old directory's attributes)
  - Then, whether `to` already existed or was just created, iterates over the files contained in `from` as if by for (const std::filesystem::directory_entry& x : std::filesystem::directory_iterator(from)) and for each directory entry, recursively calls copy(x.path(), to/x.path().filename(), options | in-recursive-copy), where in-recursive-copy is a special bit that has no other effect when set in `options`. (The sole purpose of setting this bit is to prevent recursive copying subdirectories if `options` is `copy_options::none`.)

- Otherwise does nothing

### Parameters

from | - | path to the source file, directory, or symlink
to | - | path to the target file, directory, or symlink
ec | - | out-parameter for error reporting in the non-throwing overload

### Return value

(none)

### Exceptions

The overload that does not take a std::error_code& parameter throws `filesystem_error` on underlying OS API errors, constructed with `from` as the first path argument, `to` as the second path argument, and the OS error code as the error code argument. The overload taking a std::error_code& parameter sets it to the OS API error code if an OS API call fails, and executes ec.clear() if no errors occur. Any overload not marked `noexcept` may throw std::bad_alloc if memory allocation fails.

### Notes

The default behavior when copying directories is the non-recursive copy: the files are copied, but not the subdirectories:

    // 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

While with `copy_options::recursive`, the subdirectories are also copied, with their content, recursively.

    // ...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

### Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
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

### Example

Run this code

    #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"); // copy file
        fs::copy("sandbox/dir", "sandbox/dir2"); // copy directory (non-recursive)
        // sandbox holds 2 files and 2 directories, one of which has a subdirectory
        // sandbox/file1.txt
        // sandbox/file2.txt
        // sandbox/dir2
        // sandbox/dir
        //    sandbox/dir/subdir
        fs::copy("sandbox", "sandbox/copy", fs::copy_options::recursive);
        // sandbox/copy holds copies of the above files and subdirectories
        fs::remove_all("sandbox");
    }

### See also

copy_options (C++17) | specifies semantics of copy operations (enum)
copy_symlink (C++17) | copies a symbolic link (function)
copy_file (C++17) | copies file contents (function)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/filesystem/copy&oldid=106996"