c++如何利用std::expected处理文件读写中的各种预期外错误【实战】

老瑶吖_9875

老瑶吖_9875

2026-03-25

240人浏览

原创

应显式检查std::expected的.has_value()或用if语句解包,失败时通过.error()获取std::error_code并比对标准errc;写文件需将errno转为std::error_code(errno, std::generic_category())以支持跨平台错误码;优先用std::error_code而非std::string以保障类型安全与高效分支处理;注意C++23兼容性及各平台filesystem行为差异。

c++如何利用std::expected处理文件读写中的各种预期外错误【实战】

std::expected 读文件时怎么接住 std::filesystem::read_bytes 的失败?

它不抛异常,但会返回 std::expected<:vector>, std::error_code> —— 你得显式检查,不能当普通返回值用。

常见错误是直接解包:auto data = std::filesystem::read_bytes(path).value(),一旦路径不存在或权限不足,.value() 就 std::terminate。

  • 必须先调用 .has_value() 或用 if (auto r = read_bytes(...)) { ... } 检查成功分支
  • 失败时,r.error() 是 std::error_code,可直接比对 std::errc::no_such_file_or_directory 等标准枚举
  • std::filesystem::read_bytes 在 Windows 上对某些符号链接或重解析点可能静默失败,建议搭配 std::filesystem::status 预检

写文件出错后,怎么用 std::expected 区分“磁盘满”和“只读文件系统”?

标准库没提供带 std::expected 的原子写入接口,得自己封装 std::ofstream 或 std::FILE* 调用。

关键不是“怎么封装”,而是错误码映射:C 库的 errno 值(如 ENOSPC、EROFS)必须转成 std::error_code 才能进 std::expected。

  • 别用 std::make_error_code(std::errc::...) 硬编码——那是 POSIX 错误码子集,ENOSPC 对应 std::errc::no_space_on_device,但 EROFS 不在 std::errc 里
  • 更稳妥的是用 std::error_code(errno, std::generic_category()) 构造
  • 写临时文件 + std::filesystem::rename 原子提交时,两个操作都要单独检查 std::expected,不能只验 rename

为什么 std::expected 比 std::expected 更实用?

因为错误处理要分支,不是打日志。字符串没法 switch,也不能直接和 std::errc 比较,失去类型安全。

C++14
C++14

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

下载

比如你想对“文件已存在”做覆盖逻辑,对“路径是目录”则报错退出,用 std::string 就只能 find("File exists"),脆弱又慢。

  • std::error_code 支持 == 和 .category(),能精准匹配 std::errc::file_exists 或 std::errc::is_a_directory
  • 自定义错误类型(如 enum class io_errc)也能通过 std::error_code(ec, my_category()) 接入同一套处理流程
  • 传参/返回时,std::error_code 是轻量值类型;std::string 有堆分配开销,且无法静态断言错误集合

跨平台编译时,std::expected 的兼容性陷阱在哪?

它从 C++23 才进标准,但 MSVC 19.35+、GCC 12.2+、Clang 16+ 已支持。问题不在语言特性,而在依赖的 std::filesystem 行为差异。

Windows 下 std::filesystem::read_bytes 可能因 UAC 或 OneDrive 同步状态返回不同 error_code;Linux 下 EACCES 和 EPERM 语义也不完全等价。

  • 别假设 std::errc::permission_denied 在所有平台都覆盖全部权限错误
  • CI 测试必须跑在真实目标平台,不能只靠 WSL 或 Docker 模拟
  • 如果项目需支持 C++20,别硬上 std::expected —— tl::expected 是更稳的选择,但注意其 error_type 构造语义和标准版略有不同

最易被忽略的是:std::expected 不改变底层系统调用的行为,它只帮你结构化地暴露错误。文件锁、NFS 缓存、杀毒软件拦截这些,依然得靠重试逻辑和超时控制,不是换个返回类型就能解决的。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
string转int
string转int

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

2023.08.02

7059

3

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

2023.09.21

1071

6

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

2024.03.13

1437

13

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

1029

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

3280

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1858

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2984

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6264

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

6209

6

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习