2016-01-22 60 views
-2

我在写一些代码来将字节数组压缩成一个较小的字节数组。然后我想解压:压缩正在工作,但解压缩不是

''' <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()函数。我不明白为什么:

直接从MSDN采取

enter image description here

+1

当你要解压缩,你不写到流,你从它读作[GZipStream的 –

+0

可能的复制和解压缩](http://stackoverflow.com/questions/1581694/gzipstream-and-decompression) –

+0

我写道,我试过'gzip.Read'我不想让我的问题10页长,我的所有变化尝试..感谢您的反对票。 –

回答

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

+0

我见过这样的代码,并没有工作。也就是说,'gzip.CopyTo()'函数对我来说不存在。我相信我编写的代码与.NET 3.5兼容,所以我不明白为什么Visual Studio会对我大喊'.CopyTo()' –

+0

@ E.S。 '.CopyTo()'进来.net 4.0,如果我没有错。我将使用.net 3.5兼容的答案进行编辑。 – willaien

+0

它工作!感谢您为'.CopyTo'工作! –

0

例如在the GZipStream Class

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 

看,而你试图写它的例子从decompresser流如何读取