Namespaces
Variants

std::filesystem:: copy

From ru.cppreference.net
Определено в заголовке <filesystem>
void copy ( const std:: filesystem :: path & from,
const std:: filesystem :: path & to ) ;
(1) (начиная с C++17)
(2) (начиная с C++17)
(3) (начиная с C++17)
(4) (начиная с C++17)

Копирует файлы и каталоги с различными опциями.

1,2) По умолчанию, эквивалентно (3,4) с использованием copy_options::none в качестве options .
3,4) Копирует файл или директорию from в файл или директорию to , используя параметры копирования, указанные в options . Поведение не определено, если присутствует более одной опции в любой из групп опций copy_options в options (даже в группе copy_file ).

Поведение следующее:

  • Сначала, прежде чем делать что-либо еще, получает тип и разрешения from не более чем одним вызовом
  • При необходимости получает статус to , не более чем одним вызовом
  • std::filesystem::symlink_status , если copy_options::skip_symlinks или copy_options::create_symlinks присутствует в options ;
  • std::filesystem::status в противном случае (включая случай, когда copy_options::copy_symlinks присутствует в options ).
  • Если либо from , либо to имеет определяемый реализацией file type , эффекты этой функции определяются реализацией.
  • Если from не существует, сообщает об ошибке.
  • Если from и to являются одним и тем же файлом, как определено с помощью std::filesystem::equivalent , сообщает об ошибке.
  • Если либо from , либо to не является обычным файлом, директорией или символьной ссылкой, как определено с помощью std::filesystem::is_other , сообщает об ошибке.
  • Если from является директорией, но to является обычным файлом, сообщает об ошибке.
  • Если from является символьной ссылкой, то
  • Если copy_options::skip_symlink присутствует в options , ничего не делает.
  • Иначе, если to не существует и copy_options::copy_symlinks присутствует в options , тогда ведет себя как copy_symlink ( from, to ) .
  • Иначе, сообщает об ошибке.
  • В противном случае, если from является обычным файлом, тогда
  • Если copy_options::directories_only присутствует в options , ничего не делает.
  • Иначе, если copy_options::create_symlinks присутствует в options , создает символическую ссылку на to . Примечание: from должен быть абсолютным путем, если только to не находится в текущем каталоге.
  • Иначе, если copy_options::create_hard_links присутствует в options , создает жесткую ссылку на to .
  • Иначе, если to является каталогом, то ведет себя как copy_file ( from, to / from. filename ( ) , options ) (создает копию from как файл в каталоге to ).
  • Иначе, ведет себя как copy_file ( from, to, options ) (копирует файл).
  • В противном случае, если from является директорией и copy_options::create_symlinks установлен в options , сообщает об ошибке с кодом ошибки равным std:: make_error_code ( std:: errc :: is_a_directory ) .
  • В противном случае, если from является директорией и либо options содержит copy_options::recursive , либо равен copy_options::none ,
  • Если to не существует, сначала выполняется create_directory ( to, from ) (создаёт новую директорию с копией атрибутов исходной директории).
  • Затем, независимо от того, существовал ли to ранее или был только что создан, выполняется итерация по файлам в from как если бы с помощью for ( const std:: filesystem :: directory_entry & x : std:: filesystem :: directory_iterator ( from ) ) и для каждой записи директории рекурсивно вызывается copy ( x. path ( ) , to / x. path ( ) . filename ( ) , options | in - recursive - copy ) , где in-recursive-copy — специальный бит, не оказывающий другого эффекта при установке в options . (Единственное назначение установки этого бита — предотвратить рекурсивное копирование поддиректорий, если options равен copy_options::none .)
  • В противном случае ничего не делает.

Содержание

Параметры

from - путь к исходному файлу, директории или символьной ссылке
to - путь к целевому файлу, директории или символьной ссылке
ec - выходной параметр для сообщения об ошибках в непорождающей исключения перегрузке

Возвращаемое значение

(нет)

Исключения

Любая перегрузка, не помеченная noexcept , может выбрасывать std::bad_alloc при неудачном выделении памяти.

1,3) Выбрасывает std::filesystem::filesystem_error при ошибках базового API ОС, созданный с from в качестве первого аргумента пути, to в качестве второго аргумента пути и кодом ошибки ОС в качестве аргумента кода ошибки.
2,4) Устанавливает параметр std:: error_code & в код ошибки API операционной системы при сбое вызова OS API, и выполняет ec. clear ( ) если ошибок не происходит.

Примечания

Поведение по умолчанию при копировании каталогов — это нерекурсивное копирование: файлы копируются, но подкаталоги не копируются:

// Дано
// /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 <filesystem>
#include <fstream>
#include <iostream>
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 Applied to Behavior as published Correct behavior
LWG 3013 C++17 error_code перегрузка помечена как noexcept, но может выделять память noexcept удалён
LWG 2682 C++17 попытка создания символьной ссылки для директории завершается успешно, но ничего не делает сообщает об ошибке

Смотрите также

определяет семантику операций копирования
(перечисление)
копирует символическую ссылку
(функция)
(C++17)
копирует содержимое файла
(функция)