c++如何统计文件夹中所有文件的物理占用空间总和【进阶】

酷墨同学_1936

酷墨同学_1936

2026-03-28

856人浏览

原创

GetDiskFreeSpaceEx无法统计文件夹大小,需递归遍历并用AllocationSize(Windows)或st_blocks×512(Linux/macOS)累加物理占用,注意权限、符号链接、硬链接及大文件溢出。

c++如何统计文件夹中所有文件的物理占用空间总和【进阶】

Windows 下用 GetDiskFreeSpaceEx 无法直接统计文件夹大小

这个函数只返回卷的总空间、空闲空间等全局信息,和具体文件夹无关。想算一个文件夹里所有文件占了多少物理磁盘空间(不是逻辑大小),得遍历 + 获取每个文件的「在磁盘上实际占用字节数」。

关键点在于:GetFileSizeEx 返回的是逻辑大小(比如 1KB 文件),而物理占用要看文件在磁盘上的簇(allocation unit)对齐情况——哪怕只有 1 字节,也可能占满整个簇(常见 4KB)。Windows 提供了 GetCompressedFileSizeEx?不,那是错觉;真正该用的是 GetFileInformationByHandleEx 配合 FILE_STANDARD_INFO 或更准的 FILE_INTERNAL_INFORMATION?也不对——最稳的方式是用 GetFileInformationByHandleEx + FILE_STANDARD_INFO 的 AllocationSize 字段,它表示“已为该文件分配的字节数”,即物理占用。

  • AllocationSize 是四舍五入到簇大小的值,反映真实磁盘消耗
  • 对稀疏文件、压缩/加密 NTFS 文件,AllocationSize 依然有效(不像 GetCompressedFileSize 可能返回压缩后大小)
  • 必须用句柄打开文件(CreateFile),不能只靠路径调用
  • 需要递归遍历子目录,跳过 . 和 ..,且注意符号链接循环(可用 dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT 判断)

Linux/macOS 下用 stat.st_blocks * 512 是标准解法

POSIX 的 stat() 结构体里 st_blocks 字段单位是「512 字节块」,不管文件系统块大小是多少,它都按这个单位报已分配块数。乘以 512 就是物理占用字节数(st_blocks * 512)。

注意别误用 st_size(逻辑大小)或 st_blksize(推荐 I/O 块大小,和占用无关):

  • st_blocks 对硬链接只计一次(合理,物理空间不重复)
  • 遇到挂载点(mount point)默认会跨过去,如需限制在单个文件系统,检查 stat.st_dev 是否和根目录一致
  • macOS 上 st_blocks 行为和 Linux 一致,但某些旧版本 HFS+ 可能不准,APFS 没问题
  • 用 ftw() 或 nftw() 时注意回调函数里要自己调 stat(),因为 nftw 默认传的是 struct stat *,但字段是否填充取决于 flag(如 FTW_PHYS 避免跟随符号链接)

跨平台 C++ 实现必须区分路径遍历与属性获取逻辑

C++17 的 std::filesystem 能统一遍历(recursive_directory_iterator),但获取物理占用仍需平台 API:Windows 用 GetFileInformationByHandleEx,其他系统用 stat。不能依赖 file_size()——它返回 st_size,不是物理空间。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

典型错误写法:accumulate += file_size(p) —— 这算的是所有文件逻辑大小之和,远小于真实磁盘占用(尤其小文件多时)。

  • Windows 路径要用 CreateFile 打开,注意加 FILE_FLAG_BACKUP_SEMANTICS 才能打开目录句柄(虽然这里只处理文件)
  • Linux/macOS 下 stat() 失败常见原因是权限不足(如进入 /proc 子目录),需捕获 errno == EACCES 并跳过
  • 大文件夹遍历时,避免频繁 std::filesystem::status()(它可能触发额外 syscall),优先用 iterator 自带的 symlink_status() 缓存结果
  • 累加变量必须用 uint64_t,32 位 size_t 在 >4GB 场景下溢出

容易被忽略的边界:稀疏文件、NTFS 压缩、硬链接与权限

物理空间统计不是简单相加,底层行为会影响结果。例如:

  • NTFS 压缩文件:AllocationSize 已体现压缩后实际占用,无需额外处理;但若用 GetCompressedFileSize 反而可能低估(它返回压缩流长度,不包含元数据开销)
  • 稀疏文件:AllocationSize 只计已分配区域,空洞部分不占空间,这是正确行为
  • 硬链接:多个路径指向同一 inode,stat.st_nlink > 1 时若不做去重,会重复计算物理空间——但通常不应去重,因为每个硬链接都是合法入口,用户删掉其中一个并不释放空间;所以「按路径统计」是合理策略
  • 权限:Windows 上没有读权限的文件,CreateFile 会失败(ERROR_ACCESS_DENIED),应跳过而非中止;Linux 下 stat() 同样可能失败,需检查 errno

最麻烦的是符号链接循环和挂载点穿透——除非明确需求,否则默认不跟随符号链接、不跨文件系统,比强行处理更安全。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

4994

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5151

25

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3319

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2898

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1508

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2639

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3330

4

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

1657

3

windows boot manager
windows boot manager

windows boot manager无法开机的解决方法:1、系统文件损坏,使用Windows安装光盘或USB启动盘进入恢复环境,选择修复计算机,然后选择自动修复;2、引导顺序错误,进入恢复环境,选择命令提示符,输入命令"bootrec /fixboot"和"bootrec /fixmbr",然后重新启动计算机;3、硬件问题,使用硬盘检测工具进行扫描和修复;4、重装操作系统。本专题还提供其他解决

2023.08.28

2517

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习