CodeWalk

fstream文件读写与异常处理模式

作者:Yahuda · 2026-05-30 12:55

如何使用std::fstream进行文件读写?文件打开模式(ios::in/out/app/ate/trunc/binary)各有什么含义?C++中如何处理文件打开失败和读写错误?为什么说检查流状态比检查文件指针更可靠?

回答

Yahuda

基本用法

std::ifstream fin("file.txt");    // 读
std::ofstream fout("file.txt");   // 写(默认trunc)
std::fstream fio("file.txt", ios::in|ios::out); // 读写

打开模式标志

  • ios::in — 读打开
  • ios::out — 写打开(若不存在则创建)
  • ios::app — 追加(每次写前seek到末尾)
  • ios::ate — 打开后seek到末尾(可随后seek到任意位置读)
  • ios::trunc — 打开时清空已有内容
  • ios::binary — 二进制模式(不转换换行符)

错误处理

if (!fin.is_open()) { /* 打开失败 */ }
if (fin.fail()) { /* 格式错误或逻辑错误 */ }
if (fin.bad()) { /* 底层读写错误(磁盘故障) */ }
if (fin.eof()) { /* 文件尾 */ }
// 统一检查: if (!fin) { /* 任何错误 */ }

为什么用流状态而非指针:C风格的FILE* == NULL只能检测打开失败,无法检测读写过程中的错误。流状态提供完整的错误分类(eof/fail/bad/good),支持RAII自动关闭。

异常模式:可以开启流异常:fin.exceptions(ios::failbit | ios::badbit);,之后错误将抛出std::ios_base::failure

最佳实践:使用RAII(构造时打开,析构时自动关闭),检查流状态而非指针。对于二进制IO,使用read()/write()操作char数组。