I had a compress and a decompress method that used to add an extra empty character. I managed to fix it, but I’m not sure why the fixed worked and hope somebody could explain it to me.
The Fix (-1 from buffer.length in the following line):
System.Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length - 1), 0, gzBuffer, 0, 4)
Original line:
System.Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, gzBuffer, 0, 4)
The Functions:
Private Function Compress(ByVal bytes As Byte()) As Byte()
Using ms As New MemoryStream()
Using zip As New Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.BestCompression, True)
zip.Write(bytes, 0, bytes.Length)
End Using
//ms.Position = 0
Dim compressed As Byte() = ms.ToArray()
Dim gzBuffer(compressed.Length + 4) As Byte
System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length)
System.Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length -1), 0, gzBuffer, 0, 4)
Return gzBuffer
End Using
End Function
Private Function DeCompress(ByVal bytes As Byte()) As Byte()
Using ms As New MemoryStream()
Dim msgLength As Integer = BitConverter.ToInt32(bytes, 0)
ms.Write(bytes, 4, bytes.Length - 4)
Dim buffer(msgLength) As Byte
ms.Position = 0
Dim offset As Integer = 0
Using zip As New Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Decompress)
While offset < buffer.Length - 1
offset += zip.Read(buffer, offset, buffer.Length - offset)
End While
End Using
Return buffer
End Using
End Function
That’s better, now the length doesn’t overwrite part of the compressed data.
Now your problem is that you are not using the
Stream.Readmethod correctly. The method returns the number of bytes read, which can be less than the number of bytes requested, so you have to get that return value and repeat the read until you have all the data:Also, instead of writing a byte array to the memory stream, just create the memory stream from the array:
Instead of reading the memory stream into an array, just use the
ToArraymethod:Edit:
The one-off problem in the code was due to how arrays are created in VB, using the highest index instead of the size, so the buffer should be created using:
Using the
Positionproperty when reading and writing the memory stream you can avoid creating extra buffers:(Note: This code uses the standard .NET
GZipStream.)