【问题标题】:Stream Flush did not work, writing MemoryStream to two destinationsStream Flush 不起作用,将 MemoryStream 写入两个目的地
【发布时间】:2016-08-30 14:53:37
【问题描述】:

尝试将一些数据从 MemoryStream 写入两个目的地。首先,我将一个 Xml 对象写入内存流,然后从内存流写入一个邮件附件和一个 Zip 对象。尽管在每一步之间都进行了 Flush 和 Rewind,但只有第二个目的地获得了数据。我该如何解决这个问题?

这是我的来源:

using (Stream XmlPartStream = new MemoryStream())
using (XmlTextWriter XmlPartWriter = new XmlTextWriter(XmlPartStream, Encoding.Unicode))
{
    XDocument TheXInvoice = TheInvoice.XInvoice(dtInvoiceLines);
    XmlPartWriter.Formatting = Formatting.Indented;//xml output will be pretty-printed
    TheXInvoice.WriteTo(XmlPartWriter);//write to the MemoryStream
    XmlPartWriter.Flush();//finish writing to MemoryStream

    XmlPartStream.Seek(0, SeekOrigin.Begin);//rewind stream (Position=0 would also work)
    Attachment XmlPart = new Attachment(XmlPartStream, InvoiceXmlName, "application/xml");
    TheMail.Attachments.Add(XmlPart);
    XmlPartStream.Flush();//finish writing from MemoryStream to Attachment
    // BUG: no bytes in the Attachment

    XmlPartStream.Seek(0, SeekOrigin.Begin);//rewind stream (Position=0 would also work)
    byte[] ZippedXml = LempelZiv.GZip(XmlPartStream);
    // OK: Entire XML in the ZippedXml

更新:

感谢评论者 rinukkusu,我尝试先发邮件,然后再压缩。现在一切正常。显然,Mail 缺少 Flush 功能,它会延迟实际读取其字节...

【问题讨论】:

  • 可能附件中的流直到你真正发送邮件才会被读取,所以压缩后光标又在末尾了。
  • 这是一件疯狂的事情,但它以前对我有用。尝试在 Flush 之前或之后添加 System.Threading.Thread.Sleep(2500)。我不记得细节了,但我以前用过这个,好像系统需要一点时间才能赶上。当然,@rinukkusu 更有可能是对的 :)
  • 我遇到了同样的问题,必须创建一个新的内存流
  • 根据stackoverflow.com/a/4266487/1845672 我必须CopyTo 第二个MemoryStream,但这给了我第二个没有数据的流。
  • @rinukkusu 可能确实是这样。我会尝试先压缩,然后邮寄。

标签: c# stream


【解决方案1】:

尝试在第一个 Flush 之后调用 XmlPartWriter.Close()

【讨论】:

  • 这也会关闭底层流,因此之后无法读取。这有什么帮助?
  • 这确实可能会迫使 Mail 快点阅读数据,但正如反对者指出的那样,这也将阻止再次从该流中读取,迫使我在阅读邮件之前进行 zip 阅读。感谢您的努力。
猜你喜欢
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多