使用std::filesystem::recursive_directory_iterator遍历目录并累加regular_file的file_size()可获逻辑大小;它跨平台、简洁,但不处理硬链接去重或稀疏文件,真实磁盘占用需os特定api。

用 std::filesystem::recursive_directory_iterator 遍历并累加文件大小
标准库从 C++17 开始提供 std::filesystem,这是获取目录磁盘占用最直接、跨平台的方式。关键不是“目录本身占多少”,而是遍历所有文件(含子目录中的)并累加 file_size()。
注意:file_size() 返回的是逻辑大小(字节数),不是磁盘实际占用(如稀疏文件、簇对齐、硬链接等)。绝大多数场景下逻辑大小已足够;若需真实磁盘占用,必须调用 OS 特定 API(见后文)。
- 必须开启 C++17 或更高标准(
-std=c++17) - Windows 下需链接
libstdc++fs(GCC)或确保 MSVC 工具链支持;Clang 在 macOS/Linux 上通常开箱即用 - 跳过符号链接指向的重复内容(默认不解引用),避免重复计数:用
std::filesystem::directory_options::skip_permission_denied和follow_symlinks控制行为
#include <filesystem>
#include <iostream><p>uintmax_t get_directory_size(const std::filesystem::path& p) {
uintmax_t total = 0;
try {
for (const auto& entry : std::filesystem::recursive_directory_iterator(p)) {
if (entry.is_regular_file()) {
total += entry.file_size();
}
}
} catch (const std::filesystem::filesystem_error& e) {
// 权限不足或路径不存在时静默跳过(或按需处理)
std::cerr </p>
<h3>Windows 下用 <code>GetDiskFreeSpaceEx</code> 和 <code>GetCompressedFileSize</code> 不适用</h3>
<p>别被名字误导:<code>GetDiskFreeSpaceEx</code> 只返回驱动器空闲/总空间,和目录无关;<code>GetCompressedFileSize</code> 仅用于单个压缩文件,不能递归统计目录。真正能反映 NTFS 实际磁盘占用的是 <code>GetFileInformationByHandleEx</code> 配合 <code>FILE_STANDARD_INFO</code> ——但它只对单个文件有效,且需手动遍历+累加,比 <code>std::filesystem</code> 更繁琐,还无法处理硬链接去重。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)"><img
src="https://img.php.cn/upload/manual/000/000/001/5d6de31fedca2993.png" alt="C函数速查手册(CHM版)" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="overflowclass">C函数速查手册(CHM版)</a>
<p class="overflowclass">C函数速查手册(CHM版)</p>
</div>
<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>除非你明确需要:
</p>
<ul>
<li>区分压缩/未压缩存储的实际字节数(如 NTFS 压缩文件)</li>
<li>统计硬链接只算一次(<code>std::filesystem::file_size()</code> 对每个硬链接都返回完整大小)</li>
</ul>
否则没必要绕开标准库。<h3>Linux/macOS 下 <code>statvfs</code> 和 <code>du</code> 命令不可替代但可参考</h3>
<p><code>statvfs()</code> 只能查挂载点信息(类似 Windows 的驱动器级),无法定位到某个目录的真实磁盘块使用量。系统命令 <code>du -sb</code> 才是权威参考:</p>
<ul>
<li>
<code>du -sb /path</code> 给出的是该路径下所有文件在磁盘上实际占用的字节数(考虑 block size、硬链接、稀疏文件)</li>
<li>C++ 程序若真需这个精度,最稳妥做法是调用 <code>popene("du -sb " + path.string().c_str(), "r")</code> 并解析输出——但引入 shell 依赖,不推荐用于生产环境</li>
<li>更底层的做法是用 <code>stat()</code> 获取每个文件的 <code>st_blocks * 512</code>(POSIX 标准块单位),再手动去重(通过 <code>st_dev</code> + <code>st_ino</code> 判断硬链接),但代码复杂度陡增</li>
</ul>
<h3>硬链接和稀疏文件会让逻辑大小 ≠ 磁盘占用</h3>
<p>这是最容易被忽略的偏差来源:</p>
<ul>
<li>两个硬链接指向同一 inode:<code>std::filesystem::file_size()</code> 对两者都返回完整大小,累加后翻倍,但磁盘只存一份</li>
<li>稀疏文件(如数据库预分配文件):逻辑大小很大,但实际只写入部分 block,<code>st_blocks * 512</code> 才反映真实占用</li>
<li>NTFS 压缩或 ReFS 比特流:文件系统层压缩后,磁盘占用远小于 <code>file_size()</code>
</li>
</ul>
<p>如果业务要求精确到字节级磁盘用量(例如配额管理、备份容量预估),必须放弃纯 C++ 标准库方案,转而使用平台特定 API 并自行处理 inode 去重与 block 统计——这部分没有银弹,得接受复杂度。</p></iostream></filesystem>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










