std::filesystem::copy
Определено в заголовке <filesystem> | ||
|---|---|---|
void copy( const std::filesystem::path& from,
const std::filesystem::path& to );
| (1) | (с C++17) |
void copy( const std::filesystem::path& from,
const std::filesystem::path& to,
std::error_code& ec );
| (2) | (с C++17) |
void copy( const std::filesystem::path& from,
const std::filesystem::path& to,
std::filesystem::copy_options options );
| (3) | (с C++17) |
void copy( const std::filesystem::path& from,
const std::filesystem::path& to,
std::filesystem::copy_options options,
std::error_code& ec );
| (4) | (с C++17) |
Копирует файлы и каталоги с различными опциями.
1,2) По умолчанию, эквивалентно (3,4) с
copy_options::none в качестве options.
3,4) Копирует файл или каталог
from в файл или каталог to, используя опции копирования, указанные в options. Поведение не определено, если в любой из групп опций copy_options в options (даже в группе copy_file) присутствует более одной опции.Поведение следующее:
- Сначала, до выполнения любых других действий, получает тип и разрешения
fromне более чем за один вызов -
std::filesystem::symlink_status, еслиcopy_options::skip_symlinks,copy_options::copy_symlinks, илиcopy_options::create_symlinksприсутствуют вoptions; -
std::filesystem::statusв противном случае. - При необходимости, получает состояние
to, не более чем за один вызов -
std::filesystem::symlink_status, еслиcopy_options::skip_symlinksилиcopy_options::create_symlinksприсутствуют вoptions; -
std::filesystem::statusв противном случае (включая случай, когдаcopy_options::copy_symlinksприсутствует вoptions). - Если у
fromилиtoесть реализационно-зависимый тип файла, то поведение этой функции реализационно-зависимо. - Если
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 ОС, если вызов API ОС завершился ошибкой, и выполняет ec.clear() в случае отсутствия ошибок.Примечания
По умолчанию, при копировании каталогов выполняется нерекурсивное копирование: файлы копируются, но подкаталоги нет:
// 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В то время как с copy_options::recursive, подкаталоги также копируются вместе с их содержимым рекурсивно.
// ...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Пример
#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"); // copy file
fs::copy("sandbox/dir", "sandbox/dir2"); // copy directory (non-recursive)
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 перегрузка отмечена noexcept, но может выделять память | noexcept удалено |
| LWG 2682 | C++17 | попытка создать символическую ссылку для каталога удаётся, но ничего не делает | выдаёт ошибку |
См. также
|
(C++17) | определяет семантику операций копирования (перечисление) |
|
(C++17) | копирует символическую ссылку (функция) |
|
(C++17) | копирует содержимое файла (функция) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/filesystem/copy