压缩有效但解压无效
Compression is working but decompression is not
我正在编写一些代码来将一个字节数组压缩成一个较小的字节数组。那我想解压一下:
''' <summary>
''' Receives bytes, returns compressed bytes.
''' </summary>
Function Compress(ByRef raw() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Compress)
gzip.Write(raw, 0, raw.Length)
End Using
Return memory.ToArray()
End Using
End Function
''' <summary>
''' Receives compressed bytes, returns bytes.
''' </summary>
Function DeCompress(ByRef compress() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Decompress)
gzip.Write(compress, 0, compress.Length)
End Using
Return memory.ToArray()
End Using
End Function
(我采用了 here 的代码)
我的压缩代码有效,但我的解压代码出现以下错误:
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.dll
Additional information: Writing to the compression stream is not
supported.
我尝试了 gzip.Read
的多种变体并交换变量。 (如果我知道如何查看 VB.NET 内部源代码,就像我可以使用 JDK 一样,也许我可以通过逆向工程找到解决方案,哦,好吧)
如何重组我的 DeCompress
函数以使其按预期工作?
编辑:
我注意到我没有投票,因为我没有显示 .Read
方法的使用。好吧,我无法遵循 .Read
算法,因为我的 VB.NET 没有 .CopyTo()
函数。我不明白为什么:
示例直接取自 the GZipStream Class 上的 MSDN:
Private Sub Decompress(ByVal fileToDecompress As FileInfo)
Using originalFileStream As FileStream = fileToDecompress.OpenRead()
Dim currentFileName As String = fileToDecompress.FullName
Dim newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length)
Using decompressedFileStream As FileStream = File.Create(newFileName)
Using decompressionStream As GZipStream = New GZipStream(originalFileStream, CompressionMode.Decompress)
decompressionStream.CopyTo(decompressedFileStream)
Console.WriteLine("Decompressed: {0}", fileToDecompress.Name)
End Using
End Using
End Using
End Sub
查看示例如何在您尝试写入时从解压缩器流中读取
解压缩时,您正在尝试写入解压缩流。这就是它现在的工作方式 - 解压缩时,它会在您读取解压缩流时从流中读取。
下面演示了快速解决方法:
''' <summary>
''' Receives bytes, returns compressed bytes.
''' </summary>
Function Compress(ByRef raw() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Compress)
gzip.Write(raw, 0, raw.Length)
End Using
Return memory.ToArray()
End Using
End Function
''' <summary>
''' Receives compressed bytes, returns bytes.
''' </summary>
Function DeCompress(ByRef compress() As Byte) As Byte()
Using output As MemoryStream = New MemoryStream()
Using memory As MemoryStream = New MemoryStream(compress)
Using gzip As GZipStream = New System.IO.Compression.GZipStream(memory, CompressionMode.Decompress)
CopyStreamToStream(gzip,output)
End Using
Return output.ToArray()
End Using
End Using
End Function
Public Shared Sub CopyStreamToStream(input As Stream, output As Stream)
Dim buffer As Byte() = New Byte(16 * 1024 - 1) {}
' Fairly arbitrary size
Dim bytesRead As Integer
While (InlineAssignHelper(bytesRead, input.Read(buffer, 0, buffer.Length))) > 0
output.Write(buffer, 0, bytesRead)
End While
End Sub
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
请注意,我现在 "memory" 从 "compress" 字节数组读取,并将其复制到新的输出流。
编辑:添加了 Stream.CopyTo()
的替代品,因为提问者必须针对 .net 3.5
我正在编写一些代码来将一个字节数组压缩成一个较小的字节数组。那我想解压一下:
''' <summary>
''' Receives bytes, returns compressed bytes.
''' </summary>
Function Compress(ByRef raw() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Compress)
gzip.Write(raw, 0, raw.Length)
End Using
Return memory.ToArray()
End Using
End Function
''' <summary>
''' Receives compressed bytes, returns bytes.
''' </summary>
Function DeCompress(ByRef compress() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Decompress)
gzip.Write(compress, 0, compress.Length)
End Using
Return memory.ToArray()
End Using
End Function
(我采用了 here 的代码)
我的压缩代码有效,但我的解压代码出现以下错误:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll
Additional information: Writing to the compression stream is not supported.
我尝试了 gzip.Read
的多种变体并交换变量。 (如果我知道如何查看 VB.NET 内部源代码,就像我可以使用 JDK 一样,也许我可以通过逆向工程找到解决方案,哦,好吧)
如何重组我的 DeCompress
函数以使其按预期工作?
编辑:
我注意到我没有投票,因为我没有显示 .Read
方法的使用。好吧,我无法遵循 .Read
算法,因为我的 VB.NET 没有 .CopyTo()
函数。我不明白为什么:
示例直接取自 the GZipStream Class 上的 MSDN:
Private Sub Decompress(ByVal fileToDecompress As FileInfo)
Using originalFileStream As FileStream = fileToDecompress.OpenRead()
Dim currentFileName As String = fileToDecompress.FullName
Dim newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length)
Using decompressedFileStream As FileStream = File.Create(newFileName)
Using decompressionStream As GZipStream = New GZipStream(originalFileStream, CompressionMode.Decompress)
decompressionStream.CopyTo(decompressedFileStream)
Console.WriteLine("Decompressed: {0}", fileToDecompress.Name)
End Using
End Using
End Using
End Sub
查看示例如何在您尝试写入时从解压缩器流中读取
解压缩时,您正在尝试写入解压缩流。这就是它现在的工作方式 - 解压缩时,它会在您读取解压缩流时从流中读取。
下面演示了快速解决方法:
''' <summary>
''' Receives bytes, returns compressed bytes.
''' </summary>
Function Compress(ByRef raw() As Byte) As Byte()
Using memory As MemoryStream = New MemoryStream()
Using gzip As GZipStream = New GZipStream(memory, CompressionMode.Compress)
gzip.Write(raw, 0, raw.Length)
End Using
Return memory.ToArray()
End Using
End Function
''' <summary>
''' Receives compressed bytes, returns bytes.
''' </summary>
Function DeCompress(ByRef compress() As Byte) As Byte()
Using output As MemoryStream = New MemoryStream()
Using memory As MemoryStream = New MemoryStream(compress)
Using gzip As GZipStream = New System.IO.Compression.GZipStream(memory, CompressionMode.Decompress)
CopyStreamToStream(gzip,output)
End Using
Return output.ToArray()
End Using
End Using
End Function
Public Shared Sub CopyStreamToStream(input As Stream, output As Stream)
Dim buffer As Byte() = New Byte(16 * 1024 - 1) {}
' Fairly arbitrary size
Dim bytesRead As Integer
While (InlineAssignHelper(bytesRead, input.Read(buffer, 0, buffer.Length))) > 0
output.Write(buffer, 0, bytesRead)
End While
End Sub
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
请注意,我现在 "memory" 从 "compress" 字节数组读取,并将其复制到新的输出流。
编辑:添加了 Stream.CopyTo()
的替代品,因为提问者必须针对 .net 3.5