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

C++使用std::filesystem遍历C盘如何避免Sharing Violation共享冲突错误

问题根因

fs::is_regular_file(fs::path)这类接收路径参数的类型判断函数,运行时会重新打开目标路径查询文件元数据。Windows系统下部分被进程独占锁定的文件(比如系统临时日志、驱动正在使用的文件)不允许额外的读取访问,就会触发32号共享冲突错误。

解决方案

方案1:使用directory_entry的缓存属性(最优)

recursive_directory_iterator返回的fs::directory_entry对象本身已经缓存了遍历阶段获取到的文件类型、大小等元数据,调用其自带的类型判断方法不需要再次访问文件,完全避免共享冲突:

  • 判断普通文件用p.is_regular_file()
  • 判断目录用p.is_directory()

方案2:使用带error_code的重载(兜底方案)

如果确实需要主动查询路径的类型(比如缓存的元数据过期的特殊场景),调用带std::error_code参数的重载,避免抛出异常,错误发生时直接跳过即可:

std::error_code ec;
bool is_regular = fs::is_regular_file(p.path(), ec);
if (ec) {
    // 出现错误直接跳过当前文件/目录
    continue;
}

额外优化:遍历阶段直接跳过排除目录

你现有代码是遍历到子文件/子目录才判断是否属于排除路径,效率较低,可以在遍历到排除目录时直接关闭递归,无需进入遍历。

修改后的完整代码示例
#include <filesystem>
#include <string>
#include <iostream>
#include <system_error>

namespace fs = std::filesystem;

int main() {
    fs::path rootPath = "C:\\";
    fs::path exclPath = rootPath / "Windows";
    fs::path drivrPath = rootPath / "drivers";

    const fs::directory_options options = fs::directory_options::skip_permission_denied;

    for (auto& p : fs::recursive_directory_iterator(rootPath, options)) {
        // 先判断是否是排除目录,是则直接跳过递归
        if (p.is_directory()) {
            if (p.path() == exclPath || p.path() == drivrPath) {
                p.disable_recursion_pending();
                continue;
            }
        }

        std::string filePath = p.path().string();
        // 直接用directory_entry的缓存方法判断类型,无共享冲突
        if (!p.is_regular_file()) {
            std::cout << filePath << std::endl;
        }
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Sad1que

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:45:00