【问题标题】:Properly Compressing a CSV utilizing GZIP Stream and Memory Stream利用 GZIP 流和内存流正确压缩 CSV
【发布时间】:2011-02-14 22:36:05
【问题描述】:

我正在使用 GZIPStream 和 MemoryStream 压缩一个 CSV 文件,并注意到结果文件有些奇怪。似乎 CSV 没有被正确识别。这会显示文件何时附加到电子邮件,但在保存在 Windows 桌面上时可以正常工作。

这是当前处理 gzip 部分的 sn-p:

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

        }

【问题讨论】:

  • 什么显示?什么表现出乎意料?代码是什么样的? 什么?如果您使用的是内存流,那么 rsult [sic] 文件是什么?
  • 顺便说一句,如果我不得不瞎猜的话:在你调用内存流上的 ToArray() 之前,gzip 流还没有关闭
  • 我包含了代码。我们注意到的是,当 GZIP 文件打开时(当附加到电子邮件时),压缩文件不是 .csv 文件(不知何故)。

标签: c# .net memorystream gzipstream


【解决方案1】:

我能够使用以下代码进行 gzip 压缩并发送 csv。在调用其 Close() 方法之前,GZipStream 不会完成写入。当创建 gzipStream 的 using 块完成时会发生这种情况。即使在 using 块完成后也关闭了流输出,仍然可以使用 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);
        }
}

【讨论】:

  • 非常感谢。你拯救了我的一天。即使刷新 GZipStream 也不起作用。需要补充一点:我们现在有了新的 GZipStream ctor,它带有一个 bool 参数来表示:“live open my stream”。
【解决方案2】:

所有建议的答案均无效。在这里找到答案:

其中一个限制是您不能为放置在存档中的文件命名。

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

【讨论】:

    【解决方案3】:

    GZipStream 不会创建 zip 存档;它只是实现了压缩算法。

    请参阅此 MSDN 示例以创建 zip 文件:http://msdn.microsoft.com/en-us/library/ywf6dxhx.aspx

    【讨论】:

      猜你喜欢
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多