MemoryStream, не удается получить доступ к закрытому потоку

#.net #pdf-generation #memorystream #sharppdf

#.net #pdf-генерация #memorystream #sharppdf

Вопрос:

С помощью библиотеки sharpPDF я создаю поток памяти pdf, и я хочу отправить его напрямую по электронной почте. Но строка ms.Seek(…. выдает исключение ObjectDisposedException;

Не удается получить доступ к закрытому потоку.

pdf.Метод CreatePDF принимает либо строку (выходного) имени файла, либо поток (out). Но я предполагаю, что это также закрывает поток? Я не привык много работать с потоками, поэтому, не могли бы вы, пожалуйста, посоветовать, как это следует сделать?

Исходный код sharpPDF метода CreatePDF можно найти здесь:

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
  

Комментарии:

1. Покажите, пожалуйста, код, который создает ms

2. @sll, это сторонняя библиотека, я добавил ссылку на нее.

3. вероятно, это pdf. CreatePDF (ms) закрывает ms.

Ответ №1:

Один простой подход заключается в извлечении массива байтов из закрытого потока памяти и создании другого:

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

Dim email As New EmailService
email.Send(ms)
  

Обратите внимание, что можно вызвать MemoryStream.ToArray закрытый / удаленный экземпляр MemoryStream . Это даже задокументировано:

Примечание
Этот метод работает, когда MemoryStream закрыт.

Комментарии:

1. Джон, если OP получает исключение ObjectDisposedException, не сделает ли это невозможным доступ к каким-либо элементам (при условии хорошей реализации одноразового шаблона)?

2. @Charles: Нет — вы все еще можете вызвать toArray для удаленного MemoryStream. Отредактирую, чтобы прояснить это.

3. @Джон, спасибо! это работает. Однако, насколько я понимаю; Считается ли странным, что метод, принимающий параметр out-stream, закрывает поток?

4. @brettdog: Да — лично я бы не ожидал, что он это сделает. Этот код выглядит довольно мрачно и с точки зрения соглашений .NET. Честно говоря, я бы поискал альтернативные библиотеки … это не сулит ничего хорошего.

5. О, круто. (Я должен был знать, что Джон Скит в любом случае не допустил бы подобной глупой ошибки.)