2008-10-07 46 views
3

我想使用zlib API解壓縮在VB6中創建的一些數據。如何將數字轉換爲位端順序的字節數組

我已閱讀這是可能與qUncompress功能: http://doc.trolltech.com/4.4/qbytearray.html#qUncompress

我已閱讀經由readRawBytes在從QDataStream數據到一個char 陣列,這是我然後被轉換成的QByteArray用於解壓縮。 I 具有壓縮的長度和預期的解壓縮長度,但是沒有從qUncompress返回任何東西 。

但是我需要在大端格式前加預期的解壓縮長度。有沒有人做到這一點,並有一個例子?

回答

2

我沒有使用VB6 的年齡,所以我希望這是大致正確的。我想認爲那個vb6用於()進行數組索引。如果我有什麼不對,請告訴我。

看着qUncompress文檔,你應該把你的數據放在你的QByteArray從字節5開始(我假設你在這個例子中將數組索引基數設置爲1)。

假設數組名爲qArr,並且預期的未壓縮大小爲Size。 在「big-endian」表示中,第一個字節位於第一個地址處。

qArr(1) = int(Size/(256*256*256)) 
qArr(2) = 255 And int(Size/256*256) 
qArr(3) = 255 And int(Size/256) 
qArr(4) = 255 And int(Size) 

這有道理嗎?

如果您需要小端,您可以顛倒索引的順序(qArr(4) - qArr(1))並保留相同的計算。

0

它看起來像你想要C代碼解壓縮一些zlib壓縮數據。 在這種情況下,您可能實際使用zlib並將zlib數據提供給它。 zlib主頁:http://www.zlib.net/

如果我弄錯了,你能具體說明什麼是應該用於解壓縮數據的語言,以及爲什麼zlib不會是一種選擇?

+0

qCompress/qUncompress只是周圍的zlib的包裝。 – 2008-10-07 12:48:47

0
//int length; 
byte[] bigEndianBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(length)) 

相反:

//byte[] bigEndianBytes; 
int length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bigEndianBytes)) 
+0

雖然vb6中有BitConverter和IPAddress可用嗎? – 2008-10-07 11:33:41

1

這是我如何從一種格式轉換arbitary數據到另一個。

Private Type LongByte 
    H1 As Byte 
    H2 As Byte 
    L1 As Byte 
    L2 As Byte 
End Type 

Private Type LongType 
    L As Long 
End Type 

Function SwapEndian(ByVal LongData as Long) as Long 
    Dim TempL As LongType 
    Dim TempLB As LongByte 
    Dim TempVar As Long 

    TempL.L = LongData 
    LSet TempLB = TempL 
'Swap is a subroutine I wrote to swap two variables 
    Swap TempLB.H1, TempLB.L2 
    Swap TempLB.H2, TempLB.L1 
    LSet TempL = TempLB 
    TempVar = TempL.L 

    SwapEndian = TempVar 
End Function 

如果您正在使用FileIO專注打交道,那麼你可以使用TempLB

的字節字段

訣竅是使用LSET VB6

如果您使用的是.NET的一個不起眼的命令,然後做的過程要容易得多。這裏的技巧是使用MemoryStream來檢索和設置單個字節。現在你可以爲int16/int32/int64做數學運算。但是如果你正在處理浮點數據,那麼使用LSET或者MemoryStream就會更加清晰和容易調試。

如果您使用的是Framework 1.1或更高版本,那麼您有使用字節數組的BitConvertor類。

Private Structure Int32Byte 
    Public H1 As Byte 
    Public H2 As Byte 
    Public L1 As Byte 
    Public L2 As Byte 
    Public Function Convert() As Integer 
     Dim M As New MemoryStream() 
     Dim bR As IO.BinaryReader 
     Dim bW As New IO.BinaryWriter(M) 
     Swap(H1, L2) 
     Swap(H2, L1) 
     bW.Write(H1) 
     bW.Write(H2) 
     bW.Write(L1) 
     bW.Write(L2) 
     M.Seek(0, SeekOrigin.Begin) 
     bR = New IO.BinaryReader(M) 
     Convert = bR.ReadInt32() 
    End Function 
End Structure 
0

是否要預先考慮VB中的長度,使得它適合於通過qUncompress還是你想用VB製作的數據,因爲它是現在直接使用它不是從你的問題很清楚,我並在調用qUncompress之前在C++中預先定義長度。

Mike G有一個VB解決方案posted。如果你想用C++來做,那麼你有兩種選擇,可以在QByteArray的開頭添加長度,或者直接調用zlib的解壓縮。在這兩種情況下,qCompress和qUncompress的Qt源代碼(corelib/tools/qbytearray.cpp)都是很好的參考。

這是qCompress如何增加長度(爲nbytes)到bazip,壓縮數據:

bazip[0] = (nbytes & 0xff000000) >> 24; 
bazip[1] = (nbytes & 0x00ff0000) >> 16; 
bazip[2] = (nbytes & 0x0000ff00) >> 8; 
bazip[3] = (nbytes & 0x000000ff); 

其中bazip是結果的QByteArray

另外,如果你想直接調用解壓縮,而不是使用qUncompress包裝它使用的呼叫是

baunzip.resize(len); 
res = ::uncompress((uchar*)baunzip.data(), &len, 
         (uchar*)data+4, nbytes-4); 

其中baunzip是一個QByteArray。在你的情況下,你會放棄+4和-4,因爲你的數據沒有長度。

0

謝謝你的一切幫助,這很有用。

的我得到了代碼工作:

 char slideStr[currentCompressedLen]; 
     int slideByteRead = in.readRawData(slideStr, currentCompressedLen); 
     QByteArray aInCompBytes = QByteArray(slideStr, slideByteRead); 
     aInCompBytesPlusLen = aInCompBytes; 
     aInCompBytesPlusLen.prepend(QByteArray::number(currentUnCompressedLen)); 
     aInUnCompBytes.resize(currentUnCompressedLen); 
     aInUnCompBytes = qUncompress(aInCompBytesPlusLen); 
相關問題