文章目录
- [基于流的 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 ,避免格式错误 |