std::filesystem::copy
來自 cppreference.com
< cpp | filesystem
定義於標頭檔案 <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, |
(2) | (C++17 起) |
void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(3) | (C++17 起) |
void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(4) | (C++17 起) |
複製檔案和目錄,帶有多種選項。
1,2) 預設行為,等同於使用
copy_options::none
作為 options 的 (3,4)。3,4) 使用 options 指示的複製選項,將檔案或目錄 from 複製到檔案或目錄 to。如果在 options 中存在任何 copy_options 選項組中超過一個選項(即使在
copy_file
組中),則行為未定義。行為如下:
- 首先,在執行任何其他操作之前,透過至多一次呼叫來獲取 from 的型別和許可權:
- 如果 options 中存在
copy_options::skip_symlinks
、copy_options::copy_symlinks
或copy_options::create_symlinks
,則為 std::filesystem::symlink_status; - 否則為 std::filesystem::status。
- 如果 options 中存在
- 如有必要,透過至多一次呼叫來獲取 to 的狀態:
- 如果 options 中存在
copy_options::skip_symlinks
或copy_options::create_symlinks
,則為 std::filesystem::symlink_status; - 否則為 std::filesystem::status(包括 options 中存在
copy_options::copy_symlinks
的情況)。
- 如果 options 中存在
- 如果 from 或 to 具有實現定義的檔案型別,則此函式的效果是實現定義的。
- 如果 from 不存在,則報告錯誤。
- 如果 std::filesystem::equivalent 確定 from 和 to 是相同檔案,則報告錯誤。
- 如果 std::filesystem::is_other 確定 from 或 to 不是常規檔案、目錄或符號連結,則報告錯誤。
- 如果 from 是目錄,但 to 是常規檔案,則報告錯誤。
- 如果 from 是符號連結,則:
- 如果 options 中存在
copy_options::skip_symlink
,則不執行任何操作。 - 否則,如果 to 不存在且 options 中存在
copy_options::copy_symlinks
,則行為如同 copy_symlink(from, to)。 - 否則,報告錯誤。
- 如果 options 中存在
- 否則,如果 from 是常規檔案,則:
- 如果 options 中存在
copy_options::directories_only
,則不執行任何操作。 - 否則,如果 options 中存在
copy_options::create_symlinks
,則建立指向 to 的符號連結。注意:除非 to 在當前目錄中,否則 from 必須是絕對路徑。 - 否則,如果 options 中存在
copy_options::create_hard_links
,則建立指向 to 的硬連結。 - 否則,如果 to 是目錄,則行為如同 copy_file(from, to/from.filename(), options)(將 from 的副本建立為目錄 to 中的檔案)。
- 否則,行為如同 copy_file(from, to, options)(複製檔案)。
- 如果 options 中存在
- 否則,如果 from 是目錄且在 options 中設定了
copy_options::create_symlinks
,則報告錯誤,錯誤程式碼等於 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) 在底層 OS API 錯誤時丟擲 std::filesystem::filesystem_error,構造時以 from 作為第一個路徑引數,to 作為第二個路徑引數,OS 錯誤程式碼作為錯誤程式碼引數。
[編輯] 注意
複製目錄時的預設行為是非遞迴複製:檔案被複制,但子目錄不被複制。
// 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++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 3013 | C++17 | error_code 過載被標記為 noexcept 但可以分配記憶體 |
noexcept 已移除 |
LWG 2682 | C++17 | 嘗試為目錄建立符號連結成功但什麼也沒做 | 報告錯誤 |
[編輯] 另請參閱
(C++17) |
指定複製操作的語義 (列舉) |
(C++17) |
複製一個符號連結 (函式) |
(C++17) |
複製檔案內容 (函式) |