[转]c++流缓冲---rdbuf()

C++标准库封装了一个缓冲区类streambuf,以供输入输出流对象使用。每一个标准C++输出输出流对象都包含一个指向streambuf的指针,用 户能够经过调用rdbuf()成员函数得到该指针,从而直接访问底层streambuf对象。所以,能够直接对底层缓冲区进行数据读写,从而跳过上层的格 式化输入输出操做。
对于文件流类和字符串流类,分别派生了相应的流缓冲区类型,参考最后面的代码:
流对象经过调用rdbuf()得到了底层streambuf对象的指针,也就能够经过该指针调用streambuf支持你各类操做进行输入输出。本文对这些操做不予讨论,在这里主要介绍如何利用该指针实现文件内容的输出。
输出流提供了一个重载版本operator<<,它以streambuf指针为参数,实现把streambuf对象中的全部字符输出到输出流 出中;输入流也提供了一个对应的operator>>重载版本,把输入流对象中的全部字符输入到streambuf对象中。输入流的get成 员重载版本中还有以streambuf指针为参数的版本,也能够用来把输入流的东西写入到输出流缓冲区中。ios

下面用三种方法实现把一个文件的内容输出标准输出(固然还能够经过普通的标准格式化输入输出完成):
法一:经过operator<<缓存

#include <iostream> 
#include <fstream> 
using namespace std; 
int main() 
{ 
ifstream fin("source.dat"); 
cout<<fin.rdbuf(); //猜想实际上缓存的数据载体就是一个char*,而后重载了<<运算符
return 0; 
} 

法二:利用get成员函数函数

ifstream fin("source.dat"); //get里边传入什么参数,就把流的内容输入到什么里边,这是输入流的基本概念
while (!fin.get(*cout.rdbuf()).eof()) { // extract a line input 
if (fin.fail()) // blank line 
fin.clear(); 
cout<<char(fin.get()); // extract '\n' 
}

代码解释:因为上面代码中的get版本在遇到'\n'字符时,结束提取,因此须要用循环实现整个文件内容的输出。另外,当此版本get函数遇到空行 时,由于没有提取到任何字符(注意:get不提取回车符),注意会设置失败标志ios::failbit,因此此时应当调用clear()函数清除错误标 志。一样,由于该版本get不会提取回车符,因此须要用另外一版本的get()提取回车符。spa

法三:利用重载的get函数指针

ifstream fin("main.cpp"); 
fin.get(*cout.rdbuf(), EOF);

代码解释:这个版本的get成员函数能够自定义提取终止符。这里经过设置为文件结束符(EOF)来达到一下提取整个文件的目的。code

固然,你能够把上面的cout换成任意的输出流,好比文件输出流,从而能够实现文件的拷贝功能。对象

另外,上面代码中并无使用输入流的>>操做符,由于>>和<<是相对的,只是把操做数交换一下位置罢了。所以,你 能够把上面代码中用out<<blog

相关文章
相关标签/搜索