文章目录
- [基于流的 I/O](#基于流的 I/O)
-
- [流式 I/O 的核心思想](#流式 I/O 的核心思想)
- [流库的类层次结构(Class Hierarchy)](#流库的类层次结构(Class Hierarchy))
- [`<ios>` :基础控制类,定义抽象基类](#
<ios>:基础控制类,定义抽象基类) - `<streambuf>`:底层设备抽象
- [`<istream>` 和 `<ostream>`:高层输入/输出接口](#
<istream>和<ostream>:高层输入/输出接口) - 具体流实现
- [`<fstream>` :文件流(File Streams)](#
<fstream>:文件流(File Streams)) - [`<sstream>`字符串 I/O 实现](#
<sstream>字符串 I/O 实现) - [~~`<strstream>`~~ ~~数组 I/O 实现~~ (已弃用)](#
<strstream>数组 I/O 实现(已弃用)) - [`<syncstream>` 同步输出流 C++20](#
<syncstream>同步输出流 C++20) - 总结:流库的设计哲学
C++ 包含两个输入/输出库:
C 风格 I/O 函数的标准集合。<stdio.h>详解- 现代的、
基于流的 I/O 库
基于流的 I/O
在 C++ 中,基于流(Stream-based)的输入/输出机制是标准库中最核心、最灵活的 I/O 模型之一。它通过 抽象设备 和 分层类设计,实现了统一接口处理文件、内存、字符串甚至自定义设备(如压缩流、网络流等)的能力。
流式 I/O 的核心思想
C++ 的流式 I/O 库围绕"抽象 I/O 设备"组织,其核心思想是:
相同的高层代码可以操作不同的底层设备,例如:
- 文件(File)
- 内存缓冲区(Memory Buffer)
- 字符串(String)
- 自定义适配器(如压缩、加密、同步输出等)
这种灵活性得益于 类模板化设计 和 多层继承结构 ,使得用户无需关心底层细节,只需使用统一的 << 和 >> 操作符即可完成读写。
此外,所有核心类都以模板形式定义,支持任意字符类型(如 char、wchar_t、char8_t 等),并通过 typedef 为常用类型提供便捷别名(如 std::string 对应 std::basic_string<char>)
流库的类层次结构(Class Hierarchy)
以下是 C++ I/O 流库的主要类继承与组合关系(参考典型类图):

<ios> :基础控制类,定义抽象基类
-
ios_base类非模板类,管理格式化标志(如进制、填充字符)、异常掩码、事件回调等全局状态。
-
std::basic_ios<CharT, Traits>类模板: 管理任意流缓冲。继承自
ios_base,绑定到具体的字符类型和特征类(Traits),负责管理一个std::basic_streambuf<...>对象,提供状态查询(good(),fail()等)和格式化控制接口。
<streambuf>:底层设备抽象
-
std::basic_streambuf<CharT, Traits>抽象类模板,代表"原生 I/O 设备"的接口。它定义了底层字节流的读写缓冲机制(如
underflow(),overflow()),是所有具体设备实现的基础。
所有高层流类(如 ifstream, stringstream)都通过 basic_streambuf 与实际设备通信。
<istream> 和 <ostream>:高层输入/输出接口
-
std::basic_istream<CharT, Traits>提供高层输入操作(
>>,getline()等),内部持有basic_streambuf指针。 -
std::basic_ostream<CharT, Traits>提供高层输出操作(
<<,put(),flush()等)。 -
std::basic_iostream<CharT, Traits>同时继承自
basic_istream和basic_ostream,支持双向 I/O(输入+输出)。
具体流实现
| 场景 | 推荐使用 |
|---|---|
| 读写文件 | <fstream> (ifstream / ofstream) |
| 解析字符串 | <sstream> (istringstream) |
| 格式化字符串 | <sstream> (ostringstream) |
| 多线程输出 | <syncstream> (osyncstream) |
| 自定义设备 | 继承 basic_streambuf 并集成到流中 |
<fstream> :文件流(File Streams)
cpp
std::ifstream = std::basic_ifstream<char>;
std::ofstream = std::basic_ofstream<char>;
std::fstream = std::basic_fstream<char>;
-
basic_filebuf类模板:basic_filebuf<CharT, Traits>实现
basic_streambuf接口,封装操作系统文件句柄,提供文件的底层读写缓冲。 -
basic_ifstream类模板:basic_ifstream<CharT, Traits>输入文件流,实现高层文件流输入操作,继承自
basic_istream,使用basic_filebuf操作文件。 -
basic_ofstream类模板:basic_ofstream<CharT, Traits>输出文件流,实现高层文件流输出操作,继承自
basic_ostream。 -
basic_fstream类模板:basic_fstream<CharT, Traits>双向文件流,实现高层文件流输入/输出操作,继承自
basic_iostream。
<sstream>字符串 I/O 实现
cpp
std::istringstream = std::basic_istringstream<char>;
std::ostringstream = std::basic_ostringstream<char>;
std::stringstream = std::basic_stringstream<char>;
-
basic_stringbuf类模板:basic_stringbuf<CharT, Traits, Allocator>实现原生字符串设备,实现
basic_streambuf,以内存中的字符串作为存储介质。 -
basic_istringstream类模板:basic_istringstream<CharT, Traits, Allocator>实现高层字符串流输入操作,从字符串读取数据,常用于解析字符串。
-
basic_ostringstream类模板:basic_ostringstream<CharT, Traits, Allocator>实现高层字符串流输出操作,向字符串写入数据,替代
sprintf更安全。 -
basic_stringstream类模板:basic_stringstream<CharT, Traits, Allocator>实现高层字符串流输入/输出操作,支持双向操作的字符串流。
<strstream> 数组 I/O 实现 (已弃用)
提供基于 C 风格字符数组的流操作(istrstream, ostrstream)。
存在内存管理问题(需手动释放),已被 <sstream> 取代。
<syncstream> 同步输出流 C++20
多线程环境下,多个线程同时写 std::cout 会导致输出交错。为此 C++20 引入:
-
std::basic_syncbuf<CharT, Traits, Allocator>同步输出设备的包装。包装一个
basic_streambuf,确保每次写入是原子的。 -
std::basic_osyncstream<CharT, Traits, Allocator>同步输出流的包装。高层同步输出流,内部使用
syncbuf。
示例:
cpp
#include <syncstream>
#include <thread>
void worker() {
std::osyncstream sync_out(std::cout);
sync_out << "Hello from thread " << std::this_thread::get_id() << '\n';
}
优势:避免输出混乱,无需手动加锁。
总结:流库的设计哲学
| 特性 | 说明 |
|---|---|
| 抽象化 | 所有设备通过 basic_streambuf 统一抽象 |
| 模板化 | 支持任意字符类型(char, wchar_t, UTF-8等) |
| 分层设计 | 底层缓冲 vs 高层操作分离,易于扩展 |
| 可扩展性 | 可自定义 streambuf 实现压缩、加密、日志等 |
| 类型安全 | 相比 printf/scanf,避免格式错误 |