我們知道Qt中的QBitArray類支持在位(bit)的層次上進行數據操作。本文剖析該類在二進制文件讀寫時的一些要點。另外,在Qt中,QDataStream類對於二進制文件的讀寫提供了諸多便利,需要注意的是QBitArray的讀寫依賴於QDataStream類。
使用QBitArray向文件中寫數據:
QFile file("C:\\Users\\lenovo\\Desktop\\測試"); file.open(QIODevice::WriteOnly);//只寫
QDataStream input(&file); QBitArray bit(5);//構造大小為5的位數組
bit[0]=1;bit[1]=0;bit[2]=0;bit[3]=1;bit[4]=1; input<<bit;//向文件中寫入數據10011
file.close();
使用QBitArray向文件中讀數據:
QFile file("C:\\Users\\lenovo\\Desktop\\測試"); file.open(QIODevice::ReadOnly);//只讀
QDataStream output(&file); QBitArray bit;//此處不需要指定位數組的大小,后面解釋
output>>bit;//從文件中讀取數據,可以得到10011
file.close();
上面只是讀寫了一個簡單的位數組,是最簡單的例子。但是當我們需要連續多次的讀寫這種位數組時,甚至想要一位一位讀取這些位信息時,該如何處理呢?
先明確一句話:在進行讀操作時,無法根據指定的QBitArray位數組的大小(size)來讀取。也就是說實際上讀取到的size()大小,與自己設定的大小並不一致。(這個結論個人實驗得出)
以如下代碼為例:
QFile file("C:\\Users\\lenovo\\Desktop\\測試");//該文件中已經存在位信息10011
file.open(QIODevice::ReadOnly);//只讀
QDataStream output(&file); QBitArray bit(3);//此處我設置位數組的大小為3,我只想讀取3位二進制信息
output>>bit;//讀取
qDebug()<<bit.size();//輸出結果為5,顯然與我們希望的不一樣。原因后面解釋
file.close();
究竟是什么原因造成的呢??我們開始進入重點:分析這個原因我們需要分析QBitArray在文件中的編碼規則。
每一個完整的QBitArray對象,存儲進文件后,其編碼格式都是固定的:位數組的大小+位數組的實際數據。以位數據10001為例:其編碼為

(圖片中每個數字代表四個位,用16進制表示)
1、4個字節存儲該位數組的位數,00 00 00 05就表示這個位數組有5位
2、剩下部分存儲具體的位數據。可是我們的數據是1001 1為什么存儲成了19呢???原因如下:
存儲QBitArray對象時,采用的是逆存儲方式,即先存儲后四個位信息,再存儲前四個位信息。19中的 “1” 表示 “0001”,“9”表示“10001”
注意這種情況:
QFile file("C:\\Users\\lenovo\\Desktop\\測試"); file.open(QIODevice::WriteOnly);//只寫
QDataStream input(&file); QBitArray bit(5);//構造大小為5的位數組
bit[0]=1;bit[1]=0;bit[2]=0;bit[3]=1;bit[4]=1; input<<bit[0];//寫入數據
這種情況下,向文件中寫入了一個位信息,這里並沒有寫入完整的對象。那么存儲時,也就沒有完整的結構。其編碼如下圖:
相當於向文件寫入了一個數字1。如果bit[0]=0,那么相當於向文件中寫入了一個數字0。
總結:也就是說,每個QBitArray對象存儲進文件后的結構都是確定了的。所以如果想一個位一個位的讀取,那么就會破壞掉這個對象的編碼結構,以至於出現讀取錯誤的情況。想要正確的讀取出所有的位信息,必須完整的讀取每個QBitArray對象,所以在讀取的時候我們不需要設置位數組的大小。也就是說,寫入的時候寫了多少個QBitArray對象,讀取的時候就得用多少個QBitArray對象。
