You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:55:12