我們使用STL編程的時候有時候會想到把一個流對象指向的內容用另一個流對象來輸出,比如想把一個文件的內容輸出到顯示器上,我們可以用簡單的兩行代碼就可以完成:
1 ifstream infile("test.txt"); 2 cout << infile.rdbuf();
上面的代碼就把infile流對象中的流重定向到標准輸出cout上,您可以在屏幕上看到test.txt的內容。
下面的例子來自MSDN,清晰的描述了rdbuf函數的使用方法
rdbuf函數有兩種調用方法
1)無參數。返回調用者的流緩沖指針。
2)參數為流緩沖指針。它使調用者與參數(流緩沖指針)關聯,返回自己當前關聯的流緩沖區指針。
假如我們用C語言寫一個文件復制程序,比如一個mp3文件,我們首先考慮的是C語言的文件輸入輸出功能,其思路是建一個指定大小緩沖區,我們從源文件中循環讀取緩沖區大小的數據,然后寫進目的文件。而在C++中,我們拋棄了這種用字符緩沖區的按字節復制的方法,因為這種方法看起來很繁瑣,而且效率一點也不高。下面可以對比這兩種方法(程序可以直接執行):
C:
1 #include<stdlib.h> 2 #include<stdio.h> 3 int main() 4 { 5 char buf[256]; 6 FILE *pf1, *pf2; 7 if((pf1 = fopen("1.mp3", "rb")) == NULL) 8 { 9 printf("源文件打開失敗/n"); 10 return 0; 11 } 12 if((pf2 = fopen("2.mp3","wb")) == NULL) 13 { 14 printf("目標文件打開失敗/n"); 15 return 0; 16 } 17 while(fread(buf,1,256,pf1), !feof(pf1)) 18 { 19 fwrite(buf,1,256,pf2); 20 } 21 fclose(pf1); 22 fclose(pf2); 23 return 0; 24 }
C++:
1 #include<fstream> 2 #include<iostream> 3 using namespace std; 4 int main() 5 { 6 fstream fin("1.mp3",ios::in|ios::binary); 7 if(!fin.is_open()) 8 { 9 cout << "源文件打開失敗" << endl; 10 return 0; 11 } 12 fstream fout("2.mp3",ios::out|ios::binary); 13 if(! fin.is_open()) 14 { 15 cout << "目標文件打開失敗!" << endl; 16 return 0; 17 } 18 fout<<fin.rdbuf(); 19 fin.close(); 20 fout.close(); 21 return 0; 22 }
看起來是不是清晰多了呢,這就是C++中的流緩沖的威力了,程序通過把源文件的流重定向到關聯到目的文件的流對象,通過 fout<<fin.rdbuf();一句代碼就完成了在C語言中的循環讀寫緩沖區的功能,而且C++中使用的是底層的流緩沖,效率更高!