statvfs()仅返回文件系统级空间信息,无法获取用户配额;Linux需quotactl()、macOS需quota命令、Windows需WMI或管理员权限API才能读取per-user配额。

Linux 下用 statvfs() 读取文件系统配额和可用空间
Linux 没有统一的“用户配额”接口暴露给普通进程——statvfs() 返回的是整个文件系统的总/可用块数,不区分用户或组。它能告诉你 /home 还剩多少空间,但无法告诉你某用户还能写多少字节(除非你启用了磁盘配额且用 quotactl() 手动查)。
常见错误是直接拿 statvfs() 的 f_bavail 当“用户可用空间”,其实它只反映非 root 用户剩余的可用块(已扣掉 f_bfree - f_bavail 的保留块),不是配额意义上的限制。
-
f_blocks * f_frsize是文件系统总大小(字节) -
f_bfree * f_frsize是所有用户可用的空闲字节数(含 root 保留) -
f_bavail * f_frsize是非 root 用户当前可写入的字节数(更贴近实际使用场景) - 调用前必须确保路径指向挂载点,比如传
"/home"而不是"/home/user/file.txt",否则返回的是所在分区的根挂载信息,可能误判
macOS 上 statfs() 返回字段含义与 Linux 不兼容
macOS 不支持 statvfs() 的 POSIX 语义,得用 statfs()。它的 f_bavail 和 f_bfree 在 APFS 上可能相等(无保留块),且 f_fsize 和 f_frsize 常为 0,不能当块大小用——真实块大小得看 f_bsize。
更关键的是:macOS 默认不启用磁盘配额,statfs() 完全不反映 per-user 限制。如果你在做跨平台工具,别指望靠这个函数拿到一致的“用户剩余配额”。
- 用
statfs("/Users", &buf)获取挂载点信息,路径必须是挂载点本身 - 计算可用空间时,优先用
buf.f_bavail * buf.f_bsize,而不是f_frsize - 若需检查是否启用了配额,可执行
quota -u $(whoami)并解析输出;C++ 中需popen()调用,不能依赖系统调用
Windows 用 GetDiskFreeSpaceEx() 获取卷级空间,但不支持配额
Windows 的 GetDiskFreeSpaceEx() 只能返回卷(如 C:)的总、可用、空闲字节数,三个值分别对应 *lpFreeBytesAvailable、*lpTotalNumberOfBytes、*lpTotalNumberOfFreeBytes。它和 Linux/macOS 一样,对 NTFS 配额完全无感知。
NTFS 配额由内核驱动管理,普通应用必须调用 NetUserGetInfo() 或 WMI 查询 Win32_QuotaSetting,开销大且需要管理员权限。多数情况下,直接用 GetDiskFreeSpaceEx() 已足够判断磁盘是否将满。
- 传入路径必须以
"X:\"格式(结尾双反斜杠),否则可能失败或返回错误卷信息 -
lpFreeBytesAvailable是“当前用户可用字节数”,已考虑配额——但仅当该用户被显式设置了配额且启用了“拒绝写入”策略时才生效;否则它等于lpTotalNumberOfFreeBytes - 不要用
GetDiskFreeSpace(),它返回的是簇(cluster)单位,易溢出且精度低
想真正获取 per-user 配额?绕不开系统命令或特权 API
没有跨平台、免权限、纯 C++ 系统调用的方法能可靠读取用户级磁盘配额。Linux 需 quotactl() + QCMD(Q_GETQUOTA, ...),但要求进程有 CAP_SYS_ADMIN 或运行在 root 下;macOS 需 repquota 或 quota 命令;Windows 必须走 WMI 或 Net*() 系列函数,且调用者通常需 Administrators 组成员身份。
实际项目中,95% 的“磁盘使用率告警”需求只需卷级统计——这时候 statvfs()/statfs()/GetDiskFreeSpaceEx() 完全够用。真要配额,建议把检测逻辑下沉到运维脚本或后台服务里跑,前端 C++ 程序只接收 JSON 接口结果。
- Linux 下测试配额是否启用:
mount | grep "usrquota|grpquota" - 检查用户配额状态:
quota -u $USER,注意解析其输出中的blocks和hard字段 - Windows 上最轻量方式是执行
fsutil quota query C:,但需要管理员权限,普通用户会报错Access is denied
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











