如何使用Boost Filesystem复制目录? 我已经尝试过boost :: filesystem :: copy_directory(),但只创建目标目录并且不复制内容。如何使用Boost Filesystem复制目录
回答
bool copyDir(
boost::filesystem::path const & source,
boost::filesystem::path const & destination
)
{
namespace fs = boost::filesystem;
try
{
// Check whether the function call is valid
if(
!fs::exists(source) ||
!fs::is_directory(source)
)
{
std::cerr << "Source directory " << source.string()
<< " does not exist or is not a directory." << '\n'
;
return false;
}
if(fs::exists(destination))
{
std::cerr << "Destination directory " << destination.string()
<< " already exists." << '\n'
;
return false;
}
// Create the destination directory
if(!fs::create_directory(destination))
{
std::cerr << "Unable to create destination directory"
<< destination.string() << '\n'
;
return false;
}
}
catch(fs::filesystem_error const & e)
{
std::cerr << e.what() << '\n';
return false;
}
// Iterate through the source directory
for(
fs::directory_iterator file(source);
file != fs::directory_iterator(); ++file
)
{
try
{
fs::path current(file->path());
if(fs::is_directory(current))
{
// Found directory: Recursion
if(
!copyDir(
current,
destination/current.filename()
)
)
{
return false;
}
}
else
{
// Found file: Copy
fs::copy_file(
current,
destination/current.filename()
);
}
}
catch(fs::filesystem_error const & e)
{
std:: cerr << e.what() << '\n';
}
}
return true;
}
用法:
copyDir(boost::filesystem::path("/home/nijansen/test"), boost::filesystem::path("/home/nijansen/test_copy"));
(UNIX)
copyDir(boost::filesystem::path("C:\\Users\\nijansen\\test"), boost::filesystem::path("C:\\Users\\nijansen\\test2"));
(Windows)中
据我看到的,可能发生的最糟糕的是,什么也没有发生,但我赢了不承诺任何事情!使用风险自负。
请注意,您正在复制到的目录一定不存在。如果您试图复制的目录中的目录无法读取(请考虑权限管理),它们将被跳过,但其他目录仍应被复制。
更新
重构功能各自的意见。此外,该功能现在返回成功结果。如果给定目录或源目录内的任何目录的要求未得到满足,它将返回false
,但如果不能复制单个文件,则不会。
如果你使用C++,你应该使用'std :: cerr'而不是'fprintf'和'stderr'。而且,因为这是Boost.Filesystem,所以你应该使用'boost :: path'而不是'std :: string'。 – 2011-12-21 21:48:40
感谢您的建议,我相应地改进了功能。 – nijansen 2011-12-21 22:33:56
请注意,您仍然必须小心您正在复制的内容。如果你运行'copyDir(boost :: filesystem :: path(“。”),boost :: filesystem :: path(“test”))',它会复制自身直到它被终止,因为路径长度超过限制,或者磁盘空间不足。 – nijansen 2011-12-21 23:18:33
我认为这个版本是对@ nijansen的回答版本的改进。它还支持源和/或目标目录是相对的。
namespace fs = boost::filesystem;
void copyDirectoryRecursively(const fs::path& sourceDir, const fs::path& destinationDir)
{
if (!fs::exists(sourceDir) || !fs::is_directory(sourceDir))
{
throw std::runtime_error("Source directory " + sourceDir.string() + " does not exist or is not a directory");
}
if (fs::exists(destinationDir))
{
throw std::runtime_error("Destination directory " + destinationDir.string() + " already exists");
}
if (!fs::create_directory(destinationDir))
{
throw std::runtime_error("Cannot create destination directory " + destinationDir.string());
}
for (const auto& dirEnt : fs::recursive_directory_iterator{sourceDir})
{
const auto& path = dirEnt.path();
auto relativePathStr = path.string();
boost::replace_first(relativePathStr, sourceDir.string(), "");
fs::copy(path, destinationDir/relativePathStr);
}
}
的主要区别是异常而不是返回值,使用recursive_directory_iterator
和boost::replace_first
剥离迭代器路径的公共部分,依靠boost::filesystem::copy()
做不同的文件类型正确的事(保留符号链接,例如)。
用于偏好布尔返回值的异常。另外,relativePathStr可以使用path.lexically_relative(sourceDir)来计算,它可能比boost :: replace_first更简单。 – Philippe 2017-04-19 19:35:04
因为它的文件系统库已经被包含在C++ std中,所以你不需要为该任务提高性能。加入std::filesystem::copy
#include <exception>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
fs::path source = "path/to/source/folder";
fs::path target = "path/to/target/folder";
try {
fs::copy(source, target, fs::copy_options::recursive);
}
catch (std::exception& e) { // Not using fs::filesystem_error since std::bad_alloc can throw too.
// Handle exception or use error code overload of fs::copy.
}
}
非常感谢Roi。我希望游客注意你的答案。 – Ant 2017-10-20 14:25:53
注意这被添加到C++ 17中的ISO C++中。 – 2018-03-07 13:30:41
- 1. 如何在boost :: filesystem中使用copy_file?
- 2. 使用boost :: filesystem遍历目录而不会抛出异常
- 3. 在boost :: filesystem :: path中使用boost :: algorithm
- 4. boost :: filesystem normalize filename
- 5. 如何使用Ant复制目录
- 6. 使用boost :: filesystem扩展用户路径
- 7. boost :: filesystem :: exists崩溃
- 8. 使用boost :: filesystem时无法链接
- 9. 列表目录文件递归与boost :: filesystem
- 10. boost :: filesystem exists()在目录路径上失败,但is_directory()正常
- 11. 使用copyItemAtPath复制目录?
- 12. 使用NSIS复制目录。
- 13. 如何查询boost :: filesystem :: path的长度?
- 14. 如何在Windows 7上构建Boost :: FileSystem?
- 15. 如何执行boost :: filesystem copy_file覆盖
- 16. boost :: filesystem :: remove_all(path)是如何工作的?
- 17. 如何处理boost :: filesystem :: path的空格
- 18. 如何复制目录?
- 19. Laravel 5 Filesystem - 目录权限
- 20. 如何在使用boost :: filesystem时正确处理错误?
- 21. Boost函数:boost :: filesystem :: file_size错误
- 22. 如何用xcopy复制目录?
- 23. boost :: filesystem添加引号?
- 24. Boost Filesystem编译错误
- 25. boost :: filesystem :: path operator/c2296 error
- 26. Boost Filesystem - 枚举设备?
- 27. C++:boost/filesystem:一些问题
- 28. boost :: filesystem中的错误?
- 29. 删除依赖boost :: filesystem :: current_path()
- 30. boost :: filesystem :: path.parent_path()和空格
boost :: filesystem :: copy将复制目录或文件。您可以编写一个递归算法,使用该算法复制目录和文件。 – nijansen 2011-12-21 17:55:31
啊。谢谢。我很惊讶,这不是boost :: filesystem的一部分。另外,我在Boost图书馆网站上找不到任何文档,用英文说什么函数copy_directory实际上做了什么。 – Ant 2011-12-22 09:53:39