商城首页欢迎来到中国正版软件门户

您的位置:首页 >C++如何获取文件夹大小 _ 递归遍历与file_size函数【实战】

C++如何获取文件夹大小 _ 递归遍历与file_size函数【实战】

  发布于2026-05-02 阅读(0)

扫一扫,手机访问

C++如何获取文件夹大小:递归遍历与file_size函数实战

C++如何获取文件夹大小 _ 递归遍历与file_size函数【实战】

std::filesystem::file_size 需要先确认文件类型

直接对目录调用 std::filesystem::file_size 会抛出 std::filesystem::filesystem_error,错误信息通常是 “No such file or directory” 或 “Invalid argument”,不是因为路径错,而是该函数只接受普通文件(regular file)。必须先用 is_regular_file() 判断,再用 is_directory() 分流处理。

常见误写:

auto size = file_size(path); // path 是文件夹?崩溃

正确做法是:遍历前先检查类型,跳过符号链接(除非你明确要追踪)、套接字、设备文件等非数据实体。

递归遍历目录必须手动控制栈或使用 recursive_directory_iterator

C++17 的 std::filesystem::recursive_directory_iterator 是最简方案,但它默认会进入符号链接指向的目标目录——这可能导致重复计数甚至无限循环。生产环境建议禁用符号链接跟随:

立即学习“C++免费学习笔记(深入)”;

  • 构造时传入 std::filesystem::directory_options::skip_permission_denied 避免因权限失败中断
  • 显式检查 iter->is_symlink() 并跳过,而不是依赖 follow_symlinks = false(后者在部分标准库实现中行为不一致)
  • 注意:Windows 下 NTFS 符号链接和 junction point 表现不同,is_symlink() 对 junction 不返回 true,需额外判断 is_directory() + status().type() == file_type::junction

累加过程中要注意 uintmax_t 溢出与 I/O 错误静默丢弃

std::filesystem::file_size 返回 uintmax_t,单个超大文件(如 >16TB)在某些平台可能溢出,但更常见的是权限不足或路径失效导致异常。不能假设每次 file_size() 都成功:

  • file_size() 调用包在 try/catch 中,捕获 std::filesystem::filesystem_error
  • 对失败项记录警告(比如输出到 std::cerr),但不要中断整个遍历
  • 避免用 std::accumulate 一类无异常处理的泛型算法,手写循环更可控

示例关键片段:

uintmax_t total = 0;
for (auto iter = fs::recursive_directory_iterator(root, opts); iter != fs::recursive_directory_iterator(); ++iter) {
    if (iter->is_symlink()) continue;
    if (fs::is_regular_file(iter->status())) {
        try {
            total += fs::file_size(iter->path());
        } catch (const fs::filesystem_error&) {
            std::cerr << "Skip unreadable file: " << iter->path().string() << "";
        }
    }
}

Windows 下长路径和特殊目录需要额外处理

Windows 默认路径长度限制为 260 字符,\? 前缀可绕过,但 std::filesystem 在 MSVC 19.28+ 才默认启用长路径支持。若遇到 filesystem_error 提示 “The system cannot find the path specified”,优先检查:

  • 程序 manifest 是否声明 longPathAware=true
  • 注册表项 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystemLongPathsEnabled 是否为 1
  • 跳过系统保护目录(如 C:RecyclerC:System Volume Information),这些即使有管理员权限也常被拒绝访问

实际项目中,首次遍历建议加 --dry-run 模式,只统计可访问子项数量,再决定是否继续计算大小。

本文转载于:https://www.php.cn/faq/2318541.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注