std::experimental::filesystem:: copy

From cppreference.com
Defined in header <experimental/filesystem>
void copy ( const path & from, const path & to ) ;
void copy ( const path & from, const path & to, error_code & ec ) ;
(1) (filesystem TS)
void copy ( const path & from, const path & to, copy_options options ) ;
void copy ( const path & from, const path & to, copy_options options, error_code & ec ) ;
(2) (filesystem TS)

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, which is not relevant to copy ).

The behavior is as follows:

  • First, before doing anything else, obtains type and permissions of from by no more than single call to status (or, if copy_options::skip_symlinks or copy_options::create_symlinks are present in options , by a call to symlink_status ).
  • If necessary, obtains the status of to the same way, by no more than a single status or symlink_status call.
  • If from does not exist, reports an error.
  • If from and to are the same file as determined by equivalent() , reports an error.
  • If either from or to is not a regular file, a directory, or a symlink, as determined by 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 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 directory_entry & x : directory_iterator ( from ) ) and for each directory entry, recursively calls copy ( x. path ( ) , to / x. path ( ) . filename ( ) , options | unspecified ) , where unspecified 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 an error_code & parameter throws filesystem_error on underlying OS API errors, constructed with from as the first argument, to as the second argument, and the OS error code as the error code argument. std:: bad_alloc may be thrown if memory allocation fails. The overload taking an 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. This overload has
noexcept specification:
noexcept

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::experimental::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::experimental::filesystem::copy("/dir1", "/dir3", 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

Example

#include <experimental/filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::experimental::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

specifies semantics of copy operations
(enum)
copies a symbolic link
(function)
copies file contents
(function)