天天看點

32 QT - 二進制檔案讀寫

QDataStream提供了基于QIODevice的二進制資料的序列化。資料流是一種二進制流,這種流’完全不依賴于底層作業系統、CPU 或者位元組順序(大端或小端)。例如,在安裝了 Windows 平台的 PC 上面寫入的一個資料流,可以不經過任何處理,直接拿到運作了 Solaris 的 SPARC 機器上讀取。由于資料流就是二進制流,是以我們也可以直接讀寫沒有編碼的二進制資料,例如圖像、視訊、音頻等。

​QDataStream既能夠存取 C++ 基本類型,如 int、char、short 等,也可以存取複雜的資料類型,例如自定義的類。實際上,QDataStream對于類的存儲,是将複雜的類分割為很多基本單元實作的。​

結合QIODevice,QDataStream可以很友善地對檔案、網絡套接字等進行讀寫操作。我們從代碼開始看起:

QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << QString("the answer is");
out << (qint32)42;      

在這段代碼中,我們首先打開一個名為 file.dat 的檔案(注意,我們為簡單起見,并沒有檢查檔案打開是否成功,這在正式程式中是不允許的)。然後,我們将剛剛建立的file對象的指針傳遞給一個QDataStream執行個體out。類似于std::cout标準輸出流,QDataStream也重載了輸出重定向<<運算符。後面的代碼就很簡單了:将“the answer is”和數字 42 輸出到資料流。由于我們的 out 對象建立在file之上,是以相當于将問題和答案寫入file。

需要指出一點:最好使用 Qt 整型來進行讀寫,比如程式中的qint32。這保證了在任意平台和任意編譯器都能夠有相同的行為。

如果你直接運作這段代碼,你會得到一個空白的 file.dat,并沒有寫入任何資料。這是因為我們的file沒有正常關閉。為性能起見,資料隻有在檔案關閉時才會真正寫入。是以,我們必須在最後添加一行代碼:

file.close(); // 如果不想關閉檔案,可以使用 file.flush();      

接下來我們将存儲到檔案中的答案取出來:

QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 a;
in >> str >> a;      

唯一需要注意的是,你必須按照寫入的順序,将資料讀取出來。順序颠倒的話,程式行為是不确定的,嚴重時會直接造成程式崩潰。

QFile file("file.dat");
file.open(QIODevice::ReadWrite);
 
QDataStream stream(&file);
QString str = "the answer is 42";

stream << str;