使用插入符和提取符時,一般程序員不知道或不必關心數據在哪裏產生和消亡,不管處理的對象是標準I/O、文件、內存還是新創建的類或設備。
然而,重要的是與產生和消耗數據的輸入輸出流部分進行通信爲這部分提供統一的接口並隱藏底層實現,標準庫把他抽象成一個類,成爲streambuf.
每一個輸入輸出流都包含一個指針,指向某種streambuf(這依賴於它是否處理標準I / O、文件、內存等等) 。我們可以直接訪問streambuf。例如,可以向s t r e a m b u f移進、移出原始字節,而不必通過輸入輸出流來格式化
它們。當然,這是通過調用s t r e a m b u f對象的成員函數來完成的。爲了允許我們訪問s t r e a m b u f,每個流對象有一個叫做r d b u f ( )的成員函數,這個函數返回指向對象的s t r e a m b u f的指針。這樣,我們可以爲下層的 s t r e a m b u f調用任何成員函數。然而,對s t r e a m b u f指針所做的最有興趣的事之一是:使用“< <”操作符將其與另一個輸入輸出流聯結。這使我們的對象中的所有字節流進“< <”左邊的對象中。這意味着,如果把一個輸入輸出流的
所有字節移到另一個輸入輸出流,我們不必做讀入它們的一個字節或一行這樣單調的工作。
下面是打開一個文件並將其發送到標準輸出
#include <fstream>
#include <cassert>
using namespace std;
int main(){
ifstream in("test.cpp");
assert(in);
cout << in.rdbuf() ;
}
使用帶streambuf的get()函數
有一種g e t()形式允許直接向另一對象的 s t r e a m b u f寫入。第一個參數是s t r e a m b u f的目的,第二個參數是終止符,它終止g e t()函數。所以,打印一個文件到標準輸出的另一方法是:
#include<fstream>
using namespace std;
int main(){
ifstream in("test.cpp");
while(in.get(*cout.rdbuf())){
in.ignore();
}
}