c++如何检测文件流是否因磁盘配额不足而发生写入中断【进阶】

夏萱小哥_4102

夏萱小哥_4102

2026-03-26

514人浏览

原创

std::ofstream::fail() 检测不到磁盘配额超限,因为 write(2) 在配额不足时仍可能返回成功,真正报错发生在 fsync(2) 或 close(2) 时;C++ 流不暴露 errno 且析构时忽略 close 错误,必须用 POSIX 接口显式 fsync 并检查 errno == EDQUOT。

c++如何检测文件流是否因磁盘配额不足而发生写入中断【进阶】

std::ofstream::fail() 为什么检测不到磁盘配额超限?

因为磁盘配额不足时,write(2) 系统调用通常仍返回成功(写入 0 字节或部分字节),但后续 fsync(2) 或 close(2) 才真正报错 —— 而 C++ 标准流在 close() 前不主动刷盘,也不暴露底层 errno。所以仅靠 os.fail() 或 os.bad() 会漏掉配额问题。

如何捕获 write 后的 errno == EDQUOT?

必须绕过流缓冲,直接调用系统调用并检查 errno。C++ 标准库不提供接口,需用 POSIX:open() + write() + 显式 fsync() + close()。关键点是:写入后立即 fsync(),它会在配额不足时设置 errno = EDQUOT。

  • open() 用 O_SYNC 不够 —— 它只保证单次 write() 持久化,但不触发配额检查;fsync() 才强制元数据落盘,此时才爆配额错误
  • 每次 write() 后都应检查返回值是否等于请求长度;若小于,立刻查 errno(可能是 EDQUOT、ENOSPC 或 EAGAIN)
  • fsync() 返回 -1 且 errno == EDQUOT 是最可靠的配额中断信号
int fd = open("data.bin", O_WRONLY | O_CREAT, 0644);
if (fd == -1) { /* 处理 open 失败 */ }
ssize_t n = write(fd, buf, len);
if (n != len) {
    if (errno == EDQUOT || errno == ENOSPC) {
        // 配额或空间不足
    }
}
if (fsync(fd) == -1 && errno == EDQUOT) {
    // 这里才是配额耗尽的确定信号
}
close(fd);

std::ofstream 能否补救?

不能直接补救,但可辅助诊断:在 ofstream 写完后,用 fileno(os.rdbuf()) 获取底层 fd,再调用 fsync() 并检查 errno。注意:rdbuf() 必须是非 const 的,且流需处于 good 状态;os.flush() 不等价于 fsync(),它只清 C++ 缓冲区,不保持久化。

C++14
C++14

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

下载
  • os.flush() 后仍要手动 fsync(fileno(os.rdbuf()))
  • 某些 libc 实现中,std::ofstream 析构时自动 close(),但该 close() 的错误会被忽略 —— 无法捕获 EDQUOT
  • 跨平台不推荐:Windows 没有 EDQUOT,对应错误是 ERROR_DISK_FULL,需用 GetLastError()

配额检测的时机和代价

配额检查必须在数据真正落盘后做,不是写入内存缓冲区就结束。频繁 fsync() 会显著拖慢性能(尤其机械盘),但省略它就等于放弃配额感知能力。折中方案是:大文件分块写入,每写入 1–4MB 就 fsync() 一次,并检查 errno。

  • 不要依赖 statfs() 预判配额 —— 它返回的是文件系统总空间,不是用户配额(quotactl() 才能查,但 Linux 下需 root 权限)
  • 容器或 cgroup 环境下,EDQUOT 可能被替换成 ENOSPC,需同时检查两者
  • 日志类场景建议:写入前先 touch 一个临时小文件并 fsync(),快速探活配额状态

配额错误永远发生在“落盘确认”那一刻,而不是“写入调用”那一刻 —— 所有跳过 fsync() 或 close() 错误检查的逻辑,本质上都在假装它不存在。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2298

7

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3188

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

5089

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3829

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

466

15

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

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

2023.07.26

3319

3

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

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

2023.07.27

2878

6

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

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

2023.08.01

1508

3

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

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

2023.08.02

2639

5

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习