我有一个压缩和解压缩方法,用于添加一个额外的空字符。我设法解决了这个问题,但我不确定为什么固定有效,希望有人能解释一下。
修复(以下行中的buffer.length为-1):
System.Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length - 1), 0, gzBuffer, 0, 4)
原帖:
System.Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, gzBuffer, 0, 4)
功能:
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
答案 0 :(得分:2)
这样更好,现在长度不会覆盖部分压缩数据。
现在您的问题是您没有正确使用Stream.Read
方法。该方法返回读取的字节数,可以小于请求的字节数,因此您必须获取该返回值并重复读取,直到获得所有数据:
Dim offset as Integer = 0
Using zip As New Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Decompress)
Do While offset < buffer.Length
offset += zip.Read(buffer, offset, buffer.Length - offset)
Loop
End Using
此外,不是将字节数组写入内存流,只需从数组中创建内存流:
Using ms As New MemoryStream(bytes)
不要将内存流读入数组,只需使用ToArray
方法:
Dim compressed As Byte() = ms.ToArray()
代码中的一次性问题是由于如何使用最高索引而不是大小在VB中创建数组,因此应使用以下命令创建缓冲区:
Dim buffer(msgLength - 1) As Byte
在读取和写入内存流时使用Position
属性可以避免创建额外的缓冲区:
Private Function Compress(ByVal bytes As Byte()) As Byte()
Using ms As New MemoryStream()
ms.Position = 4
Using zip As New GZipStream(ms, CompressionMode.Compress, True)
zip.Write(bytes, 0, bytes.Length)
End Using
ms.Position = 0
ms.Write(BitConverter.GetBytes(bytes.Length), 0, 4)
Return ms.ToArray()
End Using
End Function
Private Function DeCompress(ByVal bytes As Byte()) As Byte()
Dim msgLength As Integer = BitConverter.ToInt32(bytes, 0)
Using ms As New MemoryStream(bytes)
Dim buffer(msgLength - 1) As Byte
ms.Position = 4
Dim offset As Integer = 0
Using zip As New GZipStream(ms, CompressionMode.Decompress)
While offset < buffer.Length
offset += zip.Read(buffer, offset, buffer.Length - offset)
End While
End Using
Return buffer
End Using
End Function
(注意:此代码使用标准.NET GZipStream
。)