我正在尝试学习有关C++中I/O流的工作原理,但我真的很困惑应该何时使用何种流。
streambuf
是什么?
与string
、istream
或vector
相比,何时使用streambuf
?(我已经了解了最后三个,但不知道streambuf
如何与它们进行比较(如果可以)。)
我正在尝试学习有关C++中I/O流的工作原理,但我真的很困惑应该何时使用何种流。
streambuf
是什么?
与string
、istream
或vector
相比,何时使用streambuf
?(我已经了解了最后三个,但不知道streambuf
如何与它们进行比较(如果可以)。)
streambuf
,我们可以在更低的层次上进行编程。它允许访问底层缓冲区。更多细节请参见:IOstream 库
流缓冲区代表输入或输出设备,并为该设备提供了无格式I/O的低级接口。另一方面,流通过基本的无格式I/O函数以及特别是格式化I/O函数(即operator<<
和operator>>
重载)提供了对缓冲区的更高级别包装器。流对象也可以管理流缓冲区的生命周期。
例如,文件流具有内部文件流缓冲区。流管理缓冲区的生命周期,而缓冲区则提供实际的读写功能。流的格式化运算符最终访问流缓冲区的无格式I/O函数,因此您只需要使用流的I/O函数,而不需要直接操作缓冲区的I/O函数。
另一种理解差异的方法是观察它们使用语言环境对象的不同方式。流使用与格式化相关的facet比如numpunct
和num_get
。您还可以期望自定义时间或货币数据类型的流operator<<
和operator>>
重载使用时间和货币格式facet。流缓冲区,然而,使用codecvt facet来在它们的接口使用的单位和字节之间进行转换。因此,例如,basic_streambuf<char16_t>
的接口使用char16_t
,因此basic_streambuf<char16_t>
默认内部使用codecvt<char16_t,char,mbstate_t>
将写入缓冲区的格式化char16_t
单位转换为写入底层设备的char
单位。因此,您可以看到流主要用于格式化,而流缓冲区为设备提供了无格式输入或输出的低级接口,该设备可能会使用不同的外部编码。
当您只需要对I/O设备进行无格式访问时,可以使用流缓冲区。如果您想设置共享流缓冲区的多个流(尽管您必须仔细管理缓冲区的生命周期),也可以使用流缓冲区。还有一些特殊用途的流缓冲区,例如C++11中的wbuffer_convert
,其充当basic_streambuf<char>
的外观,以使其看起来像宽字符流缓冲区。它使用构造时附加的codecvt facet,而不是使用任何语言环境附带的codecvt facet。通常,通过使用带有适当facet的locale的宽流缓冲区,您也可以实现相同的效果。
streambuf
用于处理原始数据(例如原始字节、原始整数等),而stream
用于处理处理过的数据(文本、格式化为文本的整数等)。换句话说,stream
代表了解析(或序列化)层。当处理纯字符串时,你可以使用其中任何一个,但含义是不同的:streambuf
表示你希望原始数据就是字符串本身,而stream
则抽象出编码方式。 - user541686stream
抽象了编码”的意思是什么吗? :D 你能再解释一下或提供更多的资料吗? - Rickstream
负责读写对象 到 streambuf
。streambuf
负责从一个字节存储位置保存和恢复字节(或字符/单词/您想称呼的任何东西)。将对象和字节进行映射就是我所说的“编码”。例如,stream
将接受一个 int
,并决定如何将其转换为 char
,反之亦然——它可以使用大端格式、小端格式、位反转格式、仅限 7 位的格式或其他任何格式。也就是说,它抽象了存储格式。 - user541686