Properly Compressing a CSV utilizing GZIP Stream and Memory Stream

4.5k views Asked by At

I am compressing a CSV file utilizing GZIPStream and MemoryStream, and noticing something weird with the result file. It seems like the CSV is not properly recognized. This shows when the file is attached to an email, but works fine when saved on a windows desktop.

Here is the current snippet handling the gzip portion:

GZipStream gStream = null;
        MemoryStream mStream = null;
        MemoryStream mStream2 = null;
        try
        {
            if (attachment.Length > 0)
            {                    
                mStream = new MemoryStream();

                gStream = new GZipStream(mStream, CompressionMode.Compress);                    
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(attachment.ToString());
                gStream.Write(bytes, 0, bytes.Length);
                gStream.Close();

                mStream2 = new MemoryStream(mStream.ToArray());
                Attachment emailAttachement = new Attachment(mStream2, "myGzip.csv.gz", "application/x-Gzip");                                         
                mailMessage.Attachments.Add(emailAttachement);
            }

        }
3

There are 3 answers

0
GeorgeU On BEST ANSWER

All the suggested answers did not work. Found the answer here:

One of the limitations is that you cannot give a name to the file that you place in the archive.

http://msdn.microsoft.com/en-us/magazine/cc163727.aspx

0
Richard Schneider On

GZipStream does NOT create a zip archive; it simply implements the compression algorithm.

See this MSDN sample for creating a zip file: http://msdn.microsoft.com/en-us/library/ywf6dxhx.aspx

1
rsbarro On

I was able to gzip compress and send a csv using the code below. GZipStream doesn't complete writing until its Close() method is called. This happens when the using block that creates gzipStream is completed. Even though the stream output is also closed once that using block is completed, the data can still be retrieved from the output stream using the ToArray() or GetBuffer() methods. Please see this blog entry for more information.

public void SendEmailWithGZippedAttachment(string fromAddress, string toAddress, string subject, string body, string attachmentText)
{
        const string filename = "myfile.csv.gz";
        var message = new MailMessage(fromAddress, toAddress, subject, body);

        //Compress and save buffer
        var output = new MemoryStream();
        using (var gzipStream = new GZipStream(output, CompressionMode.Compress))
        {
            using(var input = new MemoryStream(Encoding.UTF8.GetBytes(attachmentText)))
            {
                input.CopyTo(gzipStream);
            }
        }
        //output.ToArray is still accessible even though output is closed
        byte[] buffer = output.ToArray(); 

        //Attach and send email
        using(var stream = new MemoryStream(buffer))
        {
            message.Attachments.Add(new Attachment(stream, filename, "application/x-gzip"));
            var smtp = new SmtpClient("mail.myemailserver.com") {Credentials = new NetworkCredential("username", "password")};
            smtp.Send(message);
        }
}