压缩有效但解压无效

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