MemoryStream,无法访问已关闭的流

Posted

技术标签:

【中文标题】MemoryStream,无法访问已关闭的流【英文标题】:MemoryStream, Cannot access a closed stream 【发布时间】:2011-12-27 09:16:57 【问题描述】:

使用 sharpPDF 库,我生成了一个 pdf 内存流,我想直接通过电子邮件发送它。但是 ms.Seek(.... 行给出了 ObjectDisposedException;

无法访问已关闭的 Stream。

pdf.CreatePDF 方法采用(输出)文件名字符串或(输出)流。但我想它也会关闭流?我不习惯使用流,所以如果你能告诉我应该怎么做?

CreatePDF方法的sharpPDF源码可以在这里找到:

http://www.java2s.com/Open-Source/CSharp/PDF/SharpPDF/sharpPDF/pdfDocument.cs.htm

Public Sub SendPDF()
   Dim pdf As New sharpPDF.pdfDocument("Title", "Author")

   '....Generate pdf content

   Dim ms As New IO.MemoryStream
   pdf.CreatePDF(ms)

   Dim email As New EmailService
   email.Send(ms)

End Sub

Public Class EmailService
   Public Sub Send(Byval ms as Stream)
        ms.Seek(0, IO.SeekOrigin.Begin)

        Dim atc As New Attachment(ms, "Report.pdf")
        mail.Attachments.Add(atc)

        '....set other email parameters

        client.SendAsync(mail, mail.Subject)
  End Sub 
End Class

【问题讨论】:

请显示创建ms的代码 @sll,那是第三方库,我加了链接。 它可能是 pdf.CreatePDF(ms) 关闭了 ms。 【参考方案1】:

一种简单的方法是从封闭的 MemoryStream 中取出字节数组并创建另一个:

pdf.CreatePDF(ms)
ms = new MemoryStream(ms.ToArray())

Dim email As New EmailService
email.Send(ms)

请注意,可以在 MemoryStream 的已关闭/已处置实例上调用 MemoryStream.ToArray。它甚至被记录在案:

注意 此方法在 MemoryStream 关​​闭时有效。

【讨论】:

Jon,如果 OP 收到 ObjectDisposedException,那是不是不可能访问任何成员(假设 Disposable 模式的良好实现)? @Charles:不——您仍然可以在已处理的 MemoryStream 上调用 ToArray。将进行编辑以明确这一点。 @Jon,谢谢!这行得通。不过就我的理解而言;采用 out-stream 参数的方法关闭流是不是很奇怪? @bretddog:是的——我个人没想到它会这样做。就 .NET 约定而言,该代码看起来也很糟糕。老实说,我会寻找替代库......这不是好兆头。 哦,酷。 (我应该知道 Jon Skeet 不会犯那样愚蠢的错误。)

以上是关于MemoryStream,无法访问已关闭的流的主要内容,如果未能解决你的问题,请参考以下文章

无法写入新的 MemoryStream - 流已关闭

从 Azure 存储流式传输 blob - 无法访问已关闭的流

Azure.Storage.Blobs.ServiceRestClient.GetUserDelegationKey:System.ObjectDisposedException:无法访问已关闭的流

NPOI读取Excel报错:无法访问已关闭的流或文件

如何从 .NET 中的流中获取 MemoryStream?

使用 NAudio 读取包含作品音频的 MemoryStream