Linux用statvfs获取块大小与可用空间,quotactl获取配额;Windows用GetDiskFreeSpaceEx和GetVolumeInformation替代,配额需额外WMI或API查询,跨平台无法统一抽象。

Linux 下用 statfs 或 statvfs 能拿到块大小和配额信息,但 Windows 没有等价的单一系统调用;C++ 标准库不提供任何文件系统底层块或配额接口,必须依赖平台 API。
Linux:用 statvfs 读取块大小与可用空间
statvfs 是 POSIX 标准接口,比过时的 statfs 更可移植,返回的字段如 f_bsize(文件系统 I/O 块大小)、f_frsize(基本分配单元)、f_blocks/f_bfree/f_bavail 分别表示总块数、空闲块数、非 root 用户可用块数。
注意:f_bsize 不等于磁盘物理扇区大小(通常为 512 或 4096),它是文件系统推荐的 I/O 对齐单位;真正影响性能的是 f_frsize,多数 ext4/xfs 场景下二者相等,但 btrfs 可能不同。
实操建议:
- 传入挂载点路径(如
"/home"),不是文件路径;传错会返回ENOTBLK - 检查
statvfs()返回值是否为 0,失败时用errno判断(常见ENOENT、EPERM) - 计算可用字节数时,优先用
f_frsize * f_bavail,而非f_bsize * f_bavail,避免因对齐偏差高估空间 - 不要直接用
f_files/f_favail推算 inode 配额——它们反映当前状态,不体现用户级 quota 限制
Linux:用 quotactl 获取用户/组存储配额(需 root 或 CAP_SYS_ADMIN)
quotactl 是内核提供的配额控制入口,支持 ext4/xfs 等启用 quota 的文件系统。它不返回“剩余多少”,而是返回硬限(dqb_bhardlimit)、软限(dqb_bsoftlimit)、已用(dqb_curspace)等原始字段,需自行计算余量。
关键限制:
- 必须提前挂载时启用 quota(如
mount -o usrquota,grpquota /dev/sda1 /mnt/data) - 调用进程需有
CAP_SYS_ADMIN能力,普通用户执行会返回EPERM - 配额数据库路径固定为
"/aquota.user"或"/aquota.group"(取决于QFMT_VFS_OLD),不能自定义 -
quotactl(QCMD(Q_GETQUOTA, ...))的第四个参数必须指向struct dqblk,且uid/gid必须是目标 ID,不能填 0 代替当前用户
Windows:用 GetDiskFreeSpaceEx 和 GetVolumeInformation 替代
Windows 没有“块大小”概念,GetDiskFreeSpaceEx 直接返回字节级的 lpFreeBytesAvailable、lpTotalNumberOfBytes;而 GetVolumeInformation 中的 lpBytesPerSector 和 lpBytesPerCluster 分别对应扇区与簇大小——后者才是实际分配单位,等价于 Linux 的 f_frsize。
注意点:
-
GetDiskFreeSpaceEx不受用户配额限制影响;若启用了 NTFS 配额,需额外调用NetUserGetInfo或 WMI 查询,C++ 原生无轻量接口 - 路径必须以驱动器根结尾(如
"C:\\"),末尾反斜杠不可省略,否则返回ERROR_INVALID_PARAMETER -
lpBytesPerCluster可能为 0(如 ReFS 卷),此时应 fallback 到lpBytesPerSector并按需向上取整对齐
跨平台封装要注意的三个硬伤
写一个统一接口看似简单,但实际踩坑密集:
- Linux 配额和 Windows NTFS 配额完全异构:前者基于文件系统挂载选项+独立 quota 文件,后者绑定到用户 SID+注册表策略,无法抽象成同一模型
- “可用空间”语义分裂:Linux
f_bavail扣除保留块(通常是 5%),WindowslpFreeBytesAvailable已扣除系统保留(如还原点),但都不包含用户配额限制 - 权限模型不可桥接:Linux 的
quotactl至少需要CAP_SYS_ADMIN,Windows 查询 NTFS 配额需SE_DISK_OPERATOR_NAME权限,普通桌面程序几乎不可能同时满足
真正可行的底线方案:Linux 用 statvfs + 条件编译接入 quotactl;Windows 只用 GetDiskFreeSpaceEx + GetVolumeInformation;配额相关逻辑彻底分离,由上层业务决定是否调用、如何降级。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











