c++如何检测磁盘空间已满导致写入失败_badbit状态检查【避坑】

风晨君_7162

风晨君_7162

2026-03-24

829人浏览

原创

std::ofstream写入失败时badbit不一定被置位,因磁盘满(ENOSPC)等系统错误不自动映射到流状态;必须显式flush()后检查fail()并立即保存errno,跨平台需分别处理ENOSPC和ERROR_DISK_FULL。

c++如何检测磁盘空间已满导致写入失败_badbit状态检查【避坑】

std::ofstream 写入失败时 badbit 不一定被置位

很多人以为只要磁盘满了,ofstream 就会自动设置 badbit,结果在代码里只检查 fail() 或 bad() 却漏掉了真实错误。实际上,Linux/macOS 下磁盘满触发的是 errno == ENOSPC,而 C++ 标准流默认**不把系统 errno 映射到 stream state** —— badbit 通常只响应底层 write() 返回 -1 且 errno 非 ENOSPC 的情况(比如文件描述符失效),但写满磁盘时 write() 可能仍返回成功字节数(最后一次短写),或返回 -1 + ENOSPC,此时 ios_base::iostate 可能仍是 goodbit。

实操建议:

  • 永远不要只依赖 stream.bad() 或 stream.fail() 判断磁盘满;必须结合 errno
  • 每次调用 write()、put()、operator 后,若操作看似“成功”,但后续 flush() 或 close() 失败,问题往往出在缓冲区落盘阶段
  • 开启 exceptions() 并捕获 std::ios_base::failure 是更主动的方式,但它仍不会抛出 ENOSPC —— 你得自己查 errno

写入后必须显式 flush() + 检查 fail() 才能暴露磁盘满

因为 ofstream 默认带缓冲,数据先写进内存 buffer,等 buffer 满、flush() 或析构时才真正调用系统 write()。磁盘满的错误常卡在这一步,而不是 那一刻。

常见错误现象:os 看似没报错,但程序退出后文件为空或截断 —— 实际是 flush 阶段失败,而你没检查。

实操建议:

  • 每次关键写入后调用 os.flush(),然后立刻检查 if (os.fail()) { /* 查 errno */ }
  • 关闭前务必 os.close() 并检查返回值(close() 成功返回 true,失败返回 false,且会设 failbit)
  • 示例:
    std::ofstream os("log.txt");<br>os os.flush();<br>if (os.fail()) {<br>    if (errno == ENOSPC) {<br>        // 磁盘满<br>    }<br>}

跨平台检测 ENOSPC 要注意 errno 重置时机

errno 是线程局部的,但它的值只在系统调用失败时被设置;C++ 流操作本身不保证修改 errno,所以你不能在 os.fail() 为 true 后无条件读 errno —— 中间如果调用了任何可能改 errno 的函数(比如 std::cout ),errno 就可能被覆盖。

使用场景:日志服务、嵌入式设备本地存储、长时间运行的采集程序。

C++14
C++14

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

下载

实操建议:

  • 在 flush() 或 close() 后**立即**保存 errno,例如:int saved_errno = errno;
  • Windows 下对应错误码是 ERROR_DISK_FULL(206),需用 _doserrno 或 GetLastError(),和 POSIX 的 errno 不互通
  • 别用 std::strerror(errno) 直接打印,它不是线程安全的;优先用 std::strerror_s(MSVC)或 strerror_r(POSIX)

用 RAII 封装写入并统一错误处理比裸用 ofstream 更可靠

手动记 errno、反复 flush、检查每一步,容易漏。尤其在异常路径或提前 return 时,close() 可能根本没执行。

性能影响:RAII 封装本身无额外开销,但强制 flush() 会减少缓冲收益;可按需开关(如仅 debug 模式全 flush)。

实操建议:

  • 写一个轻量 wrapper,构造时 open,析构时 close 并检查;提供 commit() 方法显式 flush+check
  • 避免在析构里 throw 异常(违反 C++ 规则),改为记录错误码或调用回调
  • 示例核心逻辑:
    class SafeWriter {<br>    std::ofstream os;<br>    int last_errno = 0;<br>public:<br>    void commit() {<br>        os.flush();<br>        if (os.fail()) last_errno = errno;<br>    }<br>    ~SafeWriter() {<br>        os.close();<br>        if (os.fail() && !last_errno) last_errno = errno;<br>        // 处理 last_errno<br>    }<br>};

磁盘满不是流状态机的“标准错误路径”,它是系统资源层的反馈,C++ iostream 层对此保持沉默 —— 这个沉默最容易被当成“没出错”。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7099

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

3385

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

4428

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

3005

10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4618

6

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

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

2023.07.26

3399

3

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

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

2023.07.27

2938

6

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

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

2023.08.01

1528

3

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

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

2023.08.02

2679

5

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习