【问题标题】:Compression is working but decompression is not压缩有效,但解压无效
【发布时间】:2016-01-22 19:16:27
【问题描述】:

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

''' <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采用了这个代码)

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

“System.InvalidOperationException”类型的未处理异常 发生在 System.dll 中

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

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

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

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

【问题讨论】:

  • 当你要解压时,你不会写入流,而是从流中读取
  • 我写过我尝试过 gzip.Read 我不想让我的问题长达 10 页,因为我尝试了各种不同的尝试。感谢您的反对。

标签: .net vb.net gzip gzipstream


【解决方案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

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

编辑:添加了 Stream.CopyTo() 的替代品,因为提问者必须针对 .net 3.5 工作

【讨论】:

  • 我见过这样的代码,但它不起作用。也就是说,gzip.CopyTo() 函数对我来说不存在。我相信我正在编写与 .NET 3.5 兼容的代码,所以我不明白为什么 Visual Studio 对我大喊大叫 .CopyTo()
  • @E.S. .CopyTo() 来自 .net 4.0,如果我没记错的话。我将使用 .net 3.5 兼容的答案进行编辑。
  • 成功了!感谢您为.CopyTo 所做的工作!
【解决方案2】:

示例直接取自 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

查看示例在您尝试写入时如何从解压缩器流中读取数据

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2017-04-26
    • 2020-07-04
    相关资源
    最近更新 更多