我的压缩方法中的额外字符从何而来?
我有一个压缩和解压缩方法,用于添加额外的空字符。我设法修复了它,但我不确定为什么修复有效,希望有人可以向我解释一下。
修复(下一行中 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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更好了,现在长度不会覆盖部分压缩数据。
现在您的问题是您没有正确使用
Stream.Read
方法。该方法返回读取的字节数,该数可能小于请求的字节数,因此您必须获取该返回值并重复读取,直到获得所有数据:此外,不要将字节数组写入内存流,只需从数组创建内存流:
无需将内存流读入数组,只需使用 ToArray 方法:
编辑:
代码中的一次性问题是由于数组的方式造成的在VB中创建,使用最高索引而不是大小,所以应使用以下方式创建缓冲区:
在读取和写入内存流时使用
Position
属性可以避免创建额外的缓冲区:(注意:此代码使用标准 .NET
GZipStream
。 )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.Read
method 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
ToArray
method: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
Position
property when reading and writing the memory stream you can avoid creating extra buffers:(Note: This code uses the standard .NET
GZipStream
.)