使用C++递归复制目录时软链接未保留的问题求助
解决递归复制中软链接被转为普通文件的问题
你的代码当前会把软链接当成普通文件复制其内容,原因是没有单独识别并处理软链接类型。以下是修复后的完整代码,同时支持软链接、硬链接、目录和普通文件的正确递归复制:
#include <fstream> #include <filesystem> #include <iostream> #include <stdexcept> namespace fs = std::filesystem; // 复制普通文件内容 void cpFile(const fs::path & srcPath, const fs::path & dstPath) { std::ifstream srcFile(srcPath, std::ios::binary); std::ofstream dstFile(dstPath, std::ios::binary); if (!srcFile) { std::cerr << "无法打开源文件: " << srcPath << std::endl; return; } if (!dstFile) { std::cerr << "无法打开目标文件: " << dstPath << std::endl; return; } dstFile << srcFile.rdbuf(); if (!dstFile) { std::cerr << "写入目标文件失败: " << dstPath << std::endl; } srcFile.close(); dstFile.close(); } // 递归复制目录及内容 void cpDirectory(const fs::path & srcPath, const fs::path & dstPath) { try { fs::create_directories(dstPath); } catch (const fs::filesystem_error& e) { std::cerr << "创建目录失败: " << dstPath << ": " << e.what() << std::endl; return; } for (const auto & entry: fs::directory_iterator(srcPath)) { const fs::path & srcFilePath = entry.path(); const fs::path & dstFilePath = dstPath / srcFilePath.filename(); try { if (fs::is_directory(srcFilePath)) { cpDirectory(srcFilePath, dstFilePath); } else if (fs::is_symlink(srcFilePath)) { // 复制软链接本身,而非指向的文件 fs::copy_symlink(srcFilePath, dstFilePath); } else if (fs::is_regular_file(srcFilePath)) { // 处理硬链接:如果源文件是硬链接(链接数>1),创建硬链接而非复制内容 if (fs::hard_link_count(srcFilePath) > 1) { fs::create_hard_link(srcFilePath, dstFilePath); } else { cpFile(srcFilePath, dstFilePath); } } else { std::cerr << "不支持的文件类型: " << srcFilePath << std::endl; } } catch (const fs::filesystem_error& e) { std::cerr << "处理文件失败: " << srcFilePath << ": " << e.what() << std::endl; } } } int main(int argc, char *argv[]) { if (argc != 3) { std::cerr << "用法: " << argv[0] << " <源目录> <目标目录>" << std::endl; return 1; } const fs::path srcPath = argv[1]; const fs::path dstPath = argv[2]; if (!fs::exists(srcPath) || !fs::is_directory(srcPath)) { std::cerr << "源目录不存在或不是目录: " << srcPath << std::endl; return 1; } cpDirectory(srcPath, dstPath); return 0; }
关键改动说明
- 软链接处理:新增
fs::is_symlink判断,调用fs::copy_symlink直接复制链接,保留原链接的指向关系,不再复制目标文件内容。 - 硬链接处理:通过
fs::hard_link_count检查文件的硬链接数量,若大于1则创建硬链接,避免重复复制相同内容的文件。 - 错误处理增强:为所有文件系统操作添加
try-catch块,输出具体错误信息,便于定位问题。 - 参数校验:在
main函数中增加参数数量和源目录合法性的检查,避免非法输入导致的崩溃。
修复后执行./copyRec a/ e/,目标目录e/中的linkd会保留为软链接,指向d.txt,硬链接也会被正确复制。
内容的提问来源于stack exchange,提问作者Witty Apps
相关产品推荐
相关产品推荐

