1. 程式人生 > >個人對QT中QBitArray類的剖析

個人對QT中QBitArray類的剖析

我們知道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物件。