MemoryStream, Cannot access a closed stream

bretddog picture bretddog · Nov 11, 2011 · Viewed 17.9k times · Source

With the sharpPDF library I generate a pdf memory stream, and I want to send it directly via email. But the line ms.Seek(.... gives an ObjectDisposedException;

Cannot access a closed Stream.

The pdf.CreatePDF method takes either an (output) fileName string, or an (out)Stream. But I guess it also closes the stream? I'm not used to work much with streams, so if you could please advise how it should be done?

The sharpPDF source code of the CreatePDF method can be found here:

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

Answer

Jon Skeet picture Jon Skeet · Nov 11, 2011

One simple approach is to get the byte array out of the closed MemoryStream and create another one:

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

Dim email As New EmailService
email.Send(ms)

Note that it's fine to call MemoryStream.ToArray on a closed / disposed instance of MemoryStream. It's even documented:

Note
This method works when the MemoryStream is closed.