2011-02-14 35 views
2

我正在使用GZIPStream和MemoryStream压缩CSV文件,并注意到结果文件有些奇怪。看起来像CSV没有被正确识别。这显示文件何时附加到电子邮件,但保存在Windows桌面上时工作正常。正确使用GZIP流和内存流压缩CSV

这是当前片段处理gzip的部分:

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); 
      } 

     } 
+0

什么节目吗?什么行为出乎意料?代码是什么样的? *什么*?如果您使用的是内存流,那么rsult [sic]文件是什么? – 2011-02-14 22:58:34

+3

顺便说一句,如果我不得不猜测盲人:在你调用内存流的ToArray()之前,gzip流还没有关闭 – 2011-02-14 22:59:31

回答

2

我能够给gzip压缩和使用下面的代码发送一个CSV文件。在调用Close()方法之前,GZipStream不会完成写入。这发生在创建gzipStream的使用块完成时。即使流输出在使用块完成后也关闭,仍然可以使用ToArray()或GetBuffer()方法从输出流中检索数据。请参阅此blog entry以获取更多信息。

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); 
     } 
}