2016-01-22 4 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 для работы как предназначена?

EDIT: Я заметил, что я проголосовал за то, что не использовал метод использования .Read. Ну, я не могу пройти с помощью анонса .Read, потому что у моего VB.NET нет функции .CopyTo(). Я не понимаю, почему:

enter image description here

+1

Когда вы собираетесь распаковывать, вы не пишете в поток, вы читаете из него –

+0

Возможного дубликата [GZipStream и декомпрессии] (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 

Обратите внимание, что у меня теперь есть «память» чтение из «компресса» байтовый массив, и копирование его на новый выходной поток.

Edit: Добавлена ​​замена 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

Пример взят непосредственно из MSDN на 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 

Посмотрите, как пример считывает из потока декомпрессора в то время как вы пытаетесь писать в него

Смежные вопросы