GZipStream and MemoryStream

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

HI,

I tried compression in VS 2005.
Sample code bellow. Very simple task to compress byte array and then
decompress it. Compression works fine but decompression doesn't. When I use
FileStream instead of MemoryStream it works both ways. I write file and then
read it. It's probably some stupid mistake I make in decompress function. Can
anybody help?

Dim bt() As Byte =
Compress(System.Text.UnicodeEncoding.Unicode.GetBytes("AAAAAAAAAAAA")

Dim bt2() As Byte = Decompress(bt)

Public Function Compress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream()


Dim st As New GZipStream(ms, CompressionMode.Compress, True)

Dim bt(body.Length - 1) As Byte

'compress
st.Write(bt, 0, bt.Length)

st.Flush()
st.Close()
st.Dispose()

'read compressed
ms.Position = 0

Dim buffer(ms.Length) As Byte
ms.Read(buffer, 0, buffer.Length)

ms.Close()
ms.Dispose()

Return buffer

Catch ex As Exception
Debug.WriteLine("Compress: " + ex.ToString())
Throw ex
End Try

End Function

Public Function Decompress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream(body)
Dim gz As New GZipStream(ms, CompressionMode.Decompress)

Dim bt(3) As Byte

ms.Position = ms.Length - 4

ms.Read(bt, 0, 4)

ms.Position = 0

Dim size As Integer = BitConverter.ToInt32(bt, 0)

Dim buffer(size + 100) As Byte

Dim offset As Integer = 0
Dim total As Integer = 0


While (True)
Dim j As Integer = gz.Read(buffer, offset, 100) 'DOESN'T WORK
If j = 0 Then Exit While

offset += j
total += j

End While

gz.Close()
gz.Dispose()
ms.Close()
ms.Dispose()

Dim ra(total - 1) As Byte
Array.ConstrainedCopy(buffer, 0, ra, 0, total)

Return ra

Catch ex As Exception
Debug.WriteLine("Decompress: " + ex.ToString())
Throw ex
End Try

End Function

Thanks
Mark
 
Thanks Marc,

Examples are of FileStream. FileStream worked for me too. My code is very
close to one in the articles. But when I tryed MemoryStream instead of
FileStream it won't decompress. When I call Read on GZipStream nothing is
placed into buffer byte array.

Thanks
Mark
 
what is the exception?
are you sure "size" has a correct value? size=body.Length?

Mark a écrit :
 
No exception. Array size is set the same way as for FileStream (reading last
4 bytes). I even tryed to set array size of 5000, bigger than needed for
compressed "AAAAAAAAAAAA".
I pass to decompress function byte array that was compressed by compress
function.
Copy it to memory stream , pass memory stream to GZipStream in constructor.
then call read on gzip stream passing brand new byte array, offset and
number of bytes to read (100). nothing is copied into byte array, but Read
returns correct value for read bytes. Byte array stays as was initialized :
all elements = 0.

Thanks
Mark
 
Mark said:
No exception. Array size is set the same way as for FileStream (reading last
4 bytes). I even tryed to set array size of 5000, bigger than needed for
compressed "AAAAAAAAAAAA".
I pass to decompress function byte array that was compressed by compress
function.
Copy it to memory stream , pass memory stream to GZipStream in constructor.
then call read on gzip stream passing brand new byte array, offset and
number of bytes to read (100). nothing is copied into byte array, but Read
returns correct value for read bytes. Byte array stays as was initialized :
all elements = 0.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Sure , code is in my initial post.
sub Main()

Dim bt() As Byte =
Compress(System.Text.UnicodeEncoding.Unicode.GetBytes("AAAAAAAAAAAA")

Dim bt2() As Byte = Decompress(bt)

end sub

Public Function Compress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream()


Dim st As New GZipStream(ms, CompressionMode.Compress, True)

Dim bt(body.Length - 1) As Byte

'compress
st.Write(bt, 0, bt.Length)

st.Flush()
st.Close()
st.Dispose()

'read compressed
ms.Position = 0

Dim buffer(ms.Length) As Byte
ms.Read(buffer, 0, buffer.Length)

ms.Close()
ms.Dispose()

Return buffer

Catch ex As Exception
Debug.WriteLine("Compress: " + ex.ToString())
Throw ex
End Try

End Function

Public Function Decompress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream(body)
Dim gz As New GZipStream(ms, CompressionMode.Decompress)

Dim bt(3) As Byte

ms.Position = ms.Length - 4

ms.Read(bt, 0, 4)

ms.Position = 0

Dim size As Integer = BitConverter.ToInt32(bt, 0)

Dim buffer(size + 100) As Byte

Dim offset As Integer = 0
Dim total As Integer = 0


While (True)
Dim j As Integer = gz.Read(buffer, offset, 100) 'DOESN'T WORK
If j = 0 Then Exit While

offset += j
total += j

End While

gz.Close()
gz.Dispose()
ms.Close()
ms.Dispose()

Dim ra(total - 1) As Byte
Array.ConstrainedCopy(buffer, 0, ra, 0, total)

Return ra

Catch ex As Exception
Debug.WriteLine("Decompress: " + ex.ToString())
Throw ex
End Try

End Function

Thanks
Mark
 
Here you go, Hope that is OK


Imports System.IO
Imports System.IO.Compression

Module Module1

Sub Main()

Dim bt() As Byte =
Compress(System.Text.UnicodeEncoding.Unicode.GetBytes("AAAAAAAAAAAA"))
Dim bt2() As Byte = Decompress(bt)
Console.WriteLine(System.Text.UnicodeEncoding.Unicode.GetString(bt2))
Console.WriteLine("Done")
Console.ReadKey()

End Sub

Private Function Compress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream()
Dim st As New GZipStream(ms, CompressionMode.Compress, True)
Dim bt(body.Length - 1) As Byte
'compress
st.Write(bt, 0, bt.Length)
st.Flush()
st.Close()
st.Dispose()
'read compressed
ms.Position = 0
Dim buffer(ms.Length) As Byte
ms.Read(buffer, 0, buffer.Length)
ms.Close()
ms.Dispose()
Return buffer

Catch ex As Exception
Console.WriteLine("Compress: " + ex.ToString())
End Try

Return Nothing

End Function

Private Function Decompress(ByVal body() As Byte) As Byte()

Try
Dim ms As New MemoryStream(body)
Dim gz As New GZipStream(ms, CompressionMode.Decompress)
Dim bt(3) As Byte
ms.Position = ms.Length - 5
ms.Read(bt, 0, 4)
ms.Position = 0
Dim size As Integer = BitConverter.ToInt32(bt, 0)
Dim buffer(size + 100) As Byte
Dim offset As Integer = 0
Dim total As Integer = 0
While (True)
Dim j As Integer = gz.Read(buffer, offset, 100)
If j = 0 Then Exit While
offset += j
total += j
End While
gz.Close()
gz.Dispose()
ms.Close()
ms.Dispose()
Dim ra(total - 1) As Byte
Array.ConstrainedCopy(buffer, 0, ra, 0, total)
Return ra
Catch ex As Exception
Console.WriteLine("Decompress: " + ex.ToString())
End Try

Return Nothing

End Function

End Module
 
Mark said:
Here you go, Hope that is OK

Certainly is. Here's the problem:
Dim bt(body.Length - 1) As Byte
'compress
st.Write(bt, 0, bt.Length)

You're writing a bunch of 0s. Get rid of bt entirely, and instead use

st.Write (body, 0, body.Length);

Note that this is nothing to do with it being a MemoryStream - you'd
have had the same result with exactly the same code but using a
FileStream instead.
 
Thanks you. As i suspected stupid mistake!

Jon Skeet said:
Certainly is. Here's the problem:


You're writing a bunch of 0s. Get rid of bt entirely, and instead use

st.Write (body, 0, body.Length);

Note that this is nothing to do with it being a MemoryStream - you'd
have had the same result with exactly the same code but using a
FileStream instead.
 
Back
Top