使用C ++,可以将文件和目录从一个路径递归复制到另一路径
考虑以下文件系统
src/fileInRoot
src/sub_directory/
src/sub_directory/fileInSubdir
我要复制
从src
到另一个目录target
。
我创建了一个新问题,因为发现的问题是特定于平台的,并且不包含过滤器:
答案 0 :(得分:8)
是的,可以使用std C ++来复制完整的目录结构 ...从C ++ 17及其包含std::filesystem
的std::filesystem::copy
开始
1)可以使用copy_options::recursive
复制所有文件:
// Recursively copies all files and folders from src to target and overwrites existing files in target.
void CopyRecursive(const fs::path& src, const fs::path& target) noexcept
{
try
{
fs::copy(src, target, fs::copy_options::overwrite_existing | fs::copy_options::recursive);
}
catch (std::exception& e)
{
std::cout << e.what();
}
}
2)要使用过滤器复制文件的某些子集,可以使用recursive_directory_iterator
:
// Recursively copies those files and folders from src to target which matches
// predicate, and overwrites existing files in target.
void CopyRecursive(const fs::path& src, const fs::path& target,
const std::function<bool(fs::path)>& predicate /* or use template */) noexcept
{
try
{
for (const auto& dirEntry : fs::recursive_directory_iterator(src))
{
const auto& p = dirEntry.path();
if (predicate(p))
{
// Create path in target, if not existing.
const auto relativeSrc = fs::relative(p, src);
const auto targetParentPath = target / relativeSrc.parent_path();
fs::create_directories(targetParentPath);
// Copy to the targetParentPath which we just created.
fs::copy(p, targetPath, fs::copy_options::overwrite_existing);
}
}
}
catch (std::exception& e)
{
std::cout << e.what();
}
}
在调用第二种方法时
#include <filesystem>
#include <iostream>
#include <functional>
namespace fs = std::filesystem;
int main()
{
const auto root = fs::current_path();
const auto src = root / "src";
const auto target = root / "target";
// Copy only those files which contain "Sub" in their stem.
const auto filter = [](const fs::path& p) -> bool
{
return p.stem().generic_string().find("Sub") != std::string::npos;
};
CopyRecursive(src, target, filter);
}
,给定的文件系统位于进程的工作目录中,则结果为
target/sub_directory/
target/sub_directory/fileInSubdir
您还可以将copy_options
作为参数传递给CopyRecursive()
,以提高灵活性。
std::filesystem
中上面使用的一些功能的列表:
relative()
减去路径并注意符号链接
(它使用path::lexically_relative()
和weakly_canonical()
)create_directories()
为给定路径中尚不存在的每个元素创建一个目录current_path()
返回(或更改)当前工作目录的绝对路径path::stem()
返回不带扩展名的文件名path::generic_string()
给出带有平台独立目录分隔符/
对于生产代码,我建议将错误处理从实用程序功能中拉出来。对于错误处理,std::filesystem
提供了两种方法:
std::exception
/ std::filesystem::filesystem_error
std::error_code
的错误代码。还要考虑到std::filesystem
可能not be available on all platforms
如果实现无法访问分层文件系统,或者该文件系统没有提供必要的功能,则文件系统库工具可能不可用。如果某些功能不支持,则可能不可用由基础文件系统(例如FAT文件系统缺少符号链接,并禁止多个硬链接)。在这种情况下,必须报告错误。