2016-01-22 91 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流如何讀取