2

For my application, I need to upload a zipped tif image. The caveat is that the tif is downloaded from a webservice to a MemoryStream and I'm trying to avoid writing to the harddrive. What's the best way to zip this MemoryStream and copy the resulting data to another stream (Specifically, a HttpWebRequest's request stream) without saving any files to disk?

Zipping in place would also be ideal... These tif images are usually 200+ MB and I'd rather not have the image and it's zip in memory at the same time if at all avoidable. If unavoidable, I may be able to just deal with it.

Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
  • 2
    Your subject ask "Zip a memory stream but keep as stream (don't create file)?" but you mentioned "I'd rather not have the image and it's zip in memory at the same time if at all avoidable"...which one? – Saif Khan Jun 06 '11 at 15:37
  • 1
    My subject was conveying that I do not want to zip a stream into a file on the hard drive. In my details, I'm discussing that I would prefer that I zip the stream "in place" meaning to reuse the first memory stream. I wouldn't mind "emptying" the first stream into a zipped second stream if that's also possible. – Corey Ogburn Jun 06 '11 at 15:41
  • Ok then...see my post below...it passes back a ByteArray() – Saif Khan Jun 06 '11 at 15:42
  • Yes, the person that designed that API should be shot. I have been bitten by this before too. :( Try some of the other libraries available, or just pinvoke zlib. – leppie Jun 06 '11 at 15:57

3 Answers3

1

Have you taken a look at the GZipStream? This should be able to deal with most of your problems.

See: http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx

thekip
  • 3,660
  • 2
  • 21
  • 41
  • I read the example, but the image is not being compressed. Nothing at all is being written to the base stream of my GZipStream. More details at my new question: http://stackoverflow.com/questions/6255253/gzipstream-not-compressing – Corey Ogburn Jun 06 '11 at 16:43
1

Here is something I've been using in a VB.NET app...this does all in memory.

Imports System
Imports System.Collections.Generic
Imports System.IO.Compression
Imports System.IO
Imports System.Collections

Namespace Utilities

    Class Compression

        Public Shared Function Compress(ByVal data As Byte()) As Byte()
            Dim ms As New MemoryStream()
            Dim ds As New DeflateStream(ms, CompressionMode.Compress)
            ds.Write(data, 0, data.Length)
            ds.Flush()
            ds.Close()
            Return ms.ToArray()
        End Function


        Public Shared Function Decompress(ByVal data() As Byte) As Byte()
            Try

                'Copy the data (compressed) into ms.
                Using ms As New MemoryStream(data)
                    Using zipStream As Stream = New DeflateStream(ms, CompressionMode.Decompress, True)
                        'Decompressing using data stored in ms.
                        'zipStream = New DeflateStream(ms, CompressionMode.Decompress, True)
                        'Used to store the decompressed data.
                        Dim dc_data As Byte()
                        'The decompressed data is stored in zipStream; 
                        ' extract them out into a byte array.
                        dc_data = RetrieveBytesFromStream(zipStream, data.Length)
                        Return dc_data
                    End Using
                End Using
            Catch ex As Exception
                MsgBox(ex.ToString)
                Return Nothing
            End Try
        End Function

        Public Shared Function RetrieveBytesFromStream( _
       ByVal stream As Stream, ByVal bytesblock As Integer) As Byte()

            'Retrieve the bytes from a stream object.
            Dim data() As Byte
            Dim totalCount As Integer = 0
            Try
                While True
                    'Progressively increase the size of the data byte array.
                    ReDim Preserve data(totalCount + bytesblock)
                    Dim bytesRead As Integer = stream.Read(data, totalCount, bytesblock)
                    If bytesRead = 0 Then
                        Exit While
                    End If
                    totalCount += bytesRead
                End While
                'Make sure the byte array contains exactly the number
                'of bytes extracted.
                ReDim Preserve data(totalCount - 1)
                Return data
            Catch ex As Exception
                MsgBox(ex.ToString)
                Return Nothing
            End Try

        End Function

    End Class
End Namespace
Saif Khan
  • 18,402
  • 29
  • 102
  • 147
0

I am using Memory stream as well and this is what I am doing to zip/compress it and send it over the n/w.

MemoryStream st = new MemoryStream();
GZipStream zs = new GZipStream(st, CompressionMode.Compress);

zs.Write(dataSetResp.Response, 0, dataSetResp.Response.Length);
byte[] tmp = st.GetBuffer();

zs.Close();
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Kumar
  • 1
  • In order to have it working in correct way. Exchange the last two lines. GZipStream will not process all information until it is closed. So getting information before closing the stream may result in inproper function. – Ali Avcı Oct 04 '12 at 14:53