std::filesystem::space() 返回文件系统级空闲/总空间,与单个文件无关;Linux/macOS需用stat的st_blocks(512字节单位)结合st_blksize换算块数,Windows则用FILE_STANDARD_INFO的AllocationSize除以簇大小。

std::filesystem::space() 返回的是可用空间,不是文件实际占的 block 数
很多人以为 std::filesystem::space() 能直接拿到单个文件占了多少磁盘块,其实它只返回整个文件系统级别的空闲/总空间,和具体文件无关。想算某个文件真实占用的磁盘块数,得绕开这个函数,走底层 stat 系统调用。
Linux/macOS 下用 stat 结构体的 st_blocks 字段
st_blocks 是 POSIX 标准里定义的字段,单位是 512 字节(注意:不是文件系统 block size!),它反映内核为该文件实际分配的磁盘块总数(含间接块等)。要换算成你关心的「文件系统 block 大小 × 块数」,得先查 block size。
- 用
stat -f "%k" .或getconf FRAGSIZE /path查当前挂载点的最小分配单元(通常等于st_blksize) -
st_blocks * 512 / st_blksize才是真正按文件系统 block 计的整数块数(向下取整) - 示例:某文件
st_blocks == 8,st_blksize == 4096→ 实际占8 * 512 / 4096 == 1个 4K 块
Windows 下没有直接等价的 st_blocks,得用 GetCompressedFileSize 或 FILE_STANDARD_INFO
Windows 没有标准 C++ 接口暴露“分配块数”,GetFileSize() 返回逻辑大小,GetCompressedFileSize() 在启用了压缩/去重时可能更接近实际磁盘占用,但依然不等于 block 计数。更靠谱的是用 FILE_STANDARD_INFO + GetFileInformationByHandle():
-
AllocationSize字段给出按簇(cluster)对齐后的实际分配字节数 - 用
GetDiskFreeSpace()拿到每簇字节数(lpBytesPerCluster) - 真实簇数量 =
AllocationSize / lpBytesPerCluster(整除) - 注意:NTFS 压缩、稀疏文件、重解析点都会让这个值和
st_blocks行为不一致
别把 st_size 当 st_blocks —— 这是最常踩的坑
st_size 是文件逻辑字节数,完全不反映磁盘分配情况。一个 1 字节的文件在 4K block 文件系统上仍占 1 个 block;而一个 10MB 的稀疏文件(中间全是 \0)可能 st_size == 10*1024*1024,但 st_blocks 小得多。跨平台代码里混用这两个字段,结果一定错。
真正要算“磁盘上占多少 block”,核心就两条:Linux/macOS 看 st_blocks 再折算;Windows 看 AllocationSize 再除簇大小。中间没有捷径,也没有标准库函数能一键返回你想要的那个整数。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











