參考:http://www.weixueyuan.net/view/6413.htmlhtml
總結:ios
二進制文件的讀寫稍微麻煩一些,對二進制文件的讀寫一樣須要打開文件和關閉文件,打開和關閉方式與文本文件相同,只不過須要在打開方式上加上ios::binary以指明以二進制方式進行讀寫。數組
對於文本文件而言,咱們只能用ofstream類定義對象用於輸出到文件,用ifstream類定義對象用於從文件中輸入,而對於二進制文件而言,除了能夠這麼作之外,咱們還能夠用fstream類定義對象既能用於從文件輸入,又能輸出到文件中。函數
針對二進制文件的讀寫,輸入輸出類中定義了專門的函數read和write,這兩個都是類的成員函數。 spa
istream & read ( char * buffer, int size );
ostream & write ( const char * buffer, int size );
char指針buffer是指向內存中的一段存儲空間,size是存儲空間的大小,也即須要讀寫的內容的字節數。
有時咱們只須要獲取某個指定位置的數據而已,此時若是須要將數據所有讀入再找到對應位置數據實在是效率過低。爲此係統爲咱們提供了一些操做文件讀寫指針位置的成員函數,咱們可使用這些函數,將文件讀寫指針移動到指定位置並操做其中的數據。.net
函數 | 用途 |
---|---|
gcount ( ) | 返回最後一次輸入所讀入的字節數 |
tellg ( ) | 返回輸入指針的當前位置 |
seekg ( 文件中的位置 ) | 將輸入文件中指針移動到指定的位置 |
seekg ( 位移量, 參照位置 ) | 以參照位置爲標準移動指針 |
tellp ( ) | 返回輸出文件指針當前位置 |
seekp ( 文件中的位置 ) | 將輸出文件中指針移動到指定的位置 |
seekp ( 位移量, 參照位置 ) | 以參照位置爲爲標準移動指針 |
---------------------------------------------------------設計
二進制文件的讀寫稍微麻煩一些,對二進制文件的讀寫一樣須要打開文件和關閉文件,打開和關閉方式與文本文件相同,只不過須要在打開方式上加上ios::binary以指明以二進制方式進行讀寫。
對於文本文件而言,咱們只能用ofstream類定義對象用於輸出到文件,用ifstream類定義對象用於從文件中輸入,而對於二進制文件而言,除了能夠這麼作之外,咱們還能夠用fstream類定義對象既能用於從文件輸入,又能輸出到文件中。
針對二進制文件的讀寫,輸入輸出類中定義了專門的函數read和write,這兩個都是類的成員函數,它們的函數原型爲:指針
istream & read ( char * buffer, int size ); ostream & write ( const char * buffer, int size );
char指針buffer是指向內存中的一段存儲空間,size是存儲空間的大小,也即須要讀寫的內容的字節數。有了這兩個用於讀寫二進制文件的函數,咱們經過示例來看一下如何使用這兩個函數。code
例1:htm
#include <iostream> #include <fstream> using namespace std; int main() { int A[ 3 ][ 10 ] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, { 1, 2, 3, 4, 7, 7, 7, 7, 7, 7 }, { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } }; int B[ 3 ][ 10 ]; int i, j; for( i = 0; i < 3; i++ ) { for( j = 0 ; j < 10; j++ ) { cout << A[ i ][ j ] <<" "; } cout << endl; } cout << endl; //******************************************* ofstream output( "test.txt", ios::out | ios::binary ); if( ! output ) { cerr << "Open output file error!" << endl; exit( -1 ); } output.write ((char *) A, sizeof( A ) ); for( i = 0; i < 3; i++ ) { for( j = 0 ; j < 10; j++ ) { //output.write ( ( char * ) & A [ i ][ j ], sizeof( A [ i ][ j ] ) ); } } output.close(); //******************************************* ifstream input( "test.txt", ios::in | ios::binary ); if( ! input ) { cerr << "Open input file error!" << endl; exit( -1 ); } input.read( ( char * ) & B , sizeof( B ) ); for( i = 0; i < 3; i++ ) { for( j = 0 ; j < 10; j++ ) { //input.read ( ( char * ) & B[ i ][ j ], sizeof( B[ i ][ j ] )); } } for( i = 0; i < 3; i++ ) { for( j = 0 ; j < 10; j++ ) { cout << B[ i ][ j ] <<" "; } cout << endl; } //******************************************* int temp; input.seekg( 20 * sizeof( int ), ios::beg ); input.read( ( char * ) & temp, sizeof( int )); cout << temp << endl; input.close(); return 0; }
這個例子的主要功能就是先將一個二維數組以二進制的方式寫入到一個test.txt文件中,以後再從這個文件中讀出其中的數據賦值給另一個數組。咱們來細看一下這個函數的主函數,咱們一開始定義了一個數組A[ 3 ][ 10 ],並賦了初值,以後又定義了另外一個數組B[ 3 ][ 10 ],用於存放從文件中讀入的數據。程序先將A[ 3 ][ 10 ]數組中的數據打印出來。以後定義一個ofstream類的對象,以二進制方式打開文件,這種文件打開方式和文本文件打開方式是同樣的,檢測文件是否打開方法也是同樣的。文件正常打開以後,咱們就開始將A[ 3 ][ 10 ]數組中的數據以二進制的形式輸出到文件中,此時咱們經過ofstream類的對象調用write函數,由於write函數的第一個參數爲char指針,所以須要進行一次強制類型轉換,第二個參數給出了數組A[ 3 ][ 10 ]在內存中所佔空間大小。由於數組在內存中是連續存儲的,所以咱們能夠只用這麼一個語句,就將全部的數組內容以二進制的方式寫入到文本中,固然若是咱們想一個一個數據的輸出到文件也不是不能夠的,註釋掉的那個語句就是一個一個元素輸出的。以後輸出數據操做結束,關閉文件。
接下來程序開始從文件中讀入數據,打開文件也是和打開文本文件是同樣的,只是在打開方式處添加了ios::binary以指明以二進制方式打開文件。一樣的,咱們也能夠利用一個語句就將文件中的全部數據都讀入到B[ 3 ][ 10 ]數組中。以後咱們將B[ 3 ][ 10 ]數組中的數據打印出來。
固然,在程序設計過程當中,咱們有時候並不會像本例這樣的,每次都將一堆數據所有存入文件或者將一堆數據所有讀入到內存,極可能咱們只須要獲取某個指定位置的數據而已,此時若是須要將數據所有讀入在找到對應位置數據實在是效率過低。爲此系統爲咱們提供了一些操做文件讀寫指針位置的成員函數,咱們可使用這些函數,將文件讀寫指針移動到指定位置並操做其中的數據,具體函數見下表。
函數 | 用途 |
---|---|
gcount ( ) | 返回最後一次輸入所讀入的字節數 |
tellg ( ) | 返回輸入指針的當前位置 |
seekg ( 文件中的位置 ) | 將輸入文件中指針移動到指定的位置 |
seekg ( 位移量, 參照位置 ) | 以參照位置爲標準移動指針 |
tellp ( ) | 返回輸出文件指針當前位置 |
seekp ( 文件中的位置 ) | 將輸出文件中指針移動到指定的位置 |
seekp ( 位移量, 參照位置 ) | 以參照位置爲爲標準移動指針 |
表中所列函數以「g」(get的首字母)結尾的函數都是用於輸入的函數,而以「p」(put的首字母)結尾的函數都是用於輸出的函數。函數中有提到參照位置,在系統中定義了三種參照位置:
在本節例1中程序主函數的最後咱們使用seekg將文件讀寫指針以文件開頭爲標準移動20個int型數據,此時指針指向的是第三行第一列的數據,而後咱們用read函數將數據讀入到temp中,輸出temp結果確實是第三行第一列中的數據9。