C++ 文件二進制輸入輸出


文本文件和二進制文件

我們一般將文件分為文本文件和二進制文件。文本文件就是可以通過文本編輯器打開和編輯的文件,如使用Windows中的記事本(NotePad)或UNIX中的vi可以處理的文件。非文本文件都是二進制文件,我們不能直接使用文本編輯器編輯他們,而是通過計算機程序來處理的。常見的二進制文件,比如:圖片,視頻,音頻以及可執行文件。

也就是說,文本文件由字符序列構成,而二進制文件由二進制位序列構成。

但是從本質上說,文件都是二進制文件。因為對於計算機來說,它只能夠識別二進制的文件。我們所說的文本文件,其實本質也是二進制文件,只是通過編碼(encode)將二進制位轉換為了字符(編碼格式想必不用多說,常見的有ASCII,GBK,Unicode等),以便人類更好地閱讀。

因此我們說,文本I/O是建立在二進制I/O的基礎上的,在其之上提供了一層字符編碼/解碼的抽象。

二進制I/O不許要任何轉換。如果采用二進制I/O方式向文件中寫入一個數值,那么內存中存儲的值會原樣復制到文件中。

那么我們如何使用二進制I/O呢?在前邊的博客(C++ fstream和文件打開模式)提到過,要使用ios::binary打開文件。缺省條件下,文件是以文本文件打開的。

二進制文件的輸入和輸出

我們之前使用流操作符或者一些函數(put,get,getline)來讀寫文本文件。但是對於二進制文件,需要使用read和write函數,或者get、put、getline函數進行讀寫操作。

(為了方便下文用.dat文件表示二進制文件)

write函數

語法:

streamObject.write(const char* s, int size)

streamObject是流對象

s是一個字符數組

size是s的長度

下面看一個例子:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ofstream binaryio("city.dat", ios::binary);
    string city = "北京";

    binaryio.write(city.c_str(), sizeof(city));
    binaryio.close();

    cout << "二進制文件city.dat創建成功!" << endl;

    return 0;
}

運行結果:

 上面的例子中,寫入的是字符數據,但是很多情況下,我們要寫入非字符數據,如數字。那么我們可以使用reinterpret_cast來實現。此運算符可以將一個指針類型轉換為不相關的指針類型。它只是簡單地進行了指針值的二進制復制,並不改變指針所指向的數據。語法如下:

reinterpret_cast<datatype*>(address)

address是輸出數據的起始地址

datatype是希望轉換為的類型

在進行二進制I/O時,應轉換為char類型。

看下面的例子:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ofstream binaryio("temp.dat", ios::binary);
    int value = 120;

    binaryio.write(reinterpret_cast<char*>(&value), sizeof(value));
    binaryio.close();

    cout << "二進制文件temp.dat創建成功!" << endl;

    return 0;
}

運行結果:

 

 

 

 read函數

語法:

streamObject.read(const char* address, int size)

size指最大字節數,實際讀取的字符數可以從成員函數gcount中獲取。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ifstream binaryio("city.dat", ios::binary);
    char s[10];

    binaryio.read(s,10);
    cout << "讀入的字節數為:" << binaryio.gcount() << endl;
    s[binaryio.gcount()] = '\0';
    cout << s << endl;
    binaryio.close();

    return 0;
}

運行結果:

 

 如果想讀入非字符數據,那么仍然使用reinterpret_cast

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ifstream binaryio("temp.dat", ios::binary);
    int value;

    binaryio.read(reinterpret_cast<char*>(&value),sizeof(value));
    cout << "讀入的字節數為:" << binaryio.gcount() << endl;
    cout << value << endl;
    binaryio.close();

    return 0;
}

運行結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM