压缩是有效的,但减压不是

时间:2016-01-22 19:16:27

标签: .net vb.net gzip gzipstream

我正在编写一些代码来将字节数组压缩成更小的字节数组。然后我想解压缩它:

''' <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

采用了此代码

我的压缩代码有效,但我的解压缩代码出现以下错误:

  

未处理的类型&#39; System.InvalidOperationException&#39;   发生在System.dll

中      

附加信息:写入压缩流不是   支撑。

我尝试过gzip.Read的许多变体并围绕变量进行交换。 (如果我知道如何查看VB.NET内部源代码,就像我可以使用JDK一样,也许我可以通过逆向工程来解决问题,哦,好吧)

如何重新调整我的DeCompress功能以按预期工作?

编辑: 我注意到我投了票,因为我没有显示.Read方法的用法。好吧,我无法使用.Read算法,因为我的VB.NET没有.CopyTo()函数。我不明白为什么:

enter image description here

2 个答案:

答案 0 :(得分:1)

当您解压缩时,您正在尝试写入解压缩流。现在它是如何工作的 - 当解压缩时,它会在您读取解压缩流时从流中读取。

快速解决方法如下所示:

''' <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

请注意,我现在从“compress”字节数组中读取“内存”,并将其复制到新的输出流。

修改:添加Stream.CopyTo()的替代,因为提问者必须对.net 3.5

起作用

答案 1 :(得分:0)

直接从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

查看示例在您尝试写入时从解压缩器流中读取的内容