Hello,
I have a simple console application that concatenates documents, it worked very well under aspose.pdf 6.5.0.0. I recently upgraded to 6.7.0.0 and now I get this error:
Cannot access a closed Stream.
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.get_Position()
at ↔.↔.Read(Byte[] , Int32 , Int32 )
at .§.(? , , Boolean , Int64& )
at .§..(? , )
at ↓.(? , , Boolean , Int64& )
at ↓.?.(? , )
at .∟.(? , , Boolean , Int64& )
at .∟..(? streamWriter, pdfPrimitive, Int64& offset)
at ↓.(? , , Boolean , Int64& )
at ↓.?.(? streamWriter, pdfPrimitive, Int64& offset)
at ↑.∟.(? , )
at ↓.?.?()
at ↓.?.(Stream )
at ↓.?.(Stream )
at Aspose.Pdf.Document.Save(Stream output)
If I change the aspose reference back to version 6.5 it works again.
Here is the code (basically adapted from the website example):
Public Function Concatenate(ByRef Pages As List(Of Byte())) As ConcatenatedDocument
Using CombinedDocument As New Aspose.Pdf.Document()
For Each p In Pages
Using Input As New MemoryStream(p)
CombinedDocument.Pages.Add(New Aspose.Pdf.Document(Input).Pages)
End Using
Next
Using OutStream As New MemoryStream(Pages.Sum(Function(x) x.Length))
CombinedDocument.Save(OutStream)
Return New ConcatenatedDocument With {.Document = OutStream.ToArray(), .PageCount = CombinedDocument.Pages.Count}
End Using
End Using
End Function
Any help would be greatly appreciated.
Thanks,
Hi Gray,
Thank you for using our products and sharing the sample code with us. I tried using your code to test your issue but due to missing variables, I was unable to replicate the scenario at my end. However, to exactly replicate your issue at our end, we would appreciate, if you create a sample application and post here to show us the issue. This will help us to regenerate the issue and get the cause of the issue soon.
We apologize for your inconvenience.
Thanks & Regards,
Hi Rashid,
The first post contains all required information to replicate this issue.
The Pages parameter is a list of byte arrays that represent pdf documents.
The definition of the return type of ConcatenatedDocument can be inferred from the return statement: Return New ConcatentatedDocument with {.Document = Outstream.ToArray(), .PageCount = CombinedDocument.Pages.Count}
Here is the entire console application’s code:
Imports System.IO
Module Main
Sub Main()
Try
Dim License As New Aspose.Pdf.License()
License.SetLicense(“Aspose.Pdf.lic”)
Dim PcDocument As Byte()
Dim Documents As New List(Of Byte())
PcDocument = ReadFromFileSystem(“Cover.pdf”)
Documents.Add(PcDocument)
Documents.Add(ReadFromFileSystem(“Attachment2.pdf”))
Documents.Add(ReadFromFileSystem(“Attachment2.pdf”))
Dim Result As ConcatenatedDocument = Concatenate(Documents)
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine(ex.StackTrace)
Finally
Console.WriteLine(“done.”)
Console.ReadLine()
End Try
End Sub
Public Function Concatenate(ByRef Pages As List(Of Byte())) As ConcatenatedDocument
Using CombinedDocument As New Aspose.Pdf.Document()
For Each p In Pages
Using Input As New MemoryStream(p)
CombinedDocument.Pages.Add(New Aspose.Pdf.Document(Input).Pages)
End Using
Next
Using OutStream As New MemoryStream(Pages.Sum(Function(x) x.Length))
CombinedDocument.Save(OutStream)
Return New ConcatenatedDocument With {.Document = OutStream.ToArray(), .PageCount = CombinedDocument.Pages.Count}
End Using
End Using
End Function
Private Sub WriteToFileSystem(ByVal FileName As String, ByRef Document As Byte())
Using OutputFileStream As New System.IO.FileStream(FileName, System.IO.FileMode.Create)
OutputFileStream.Write(Document, 0, Document.Length)
End Using
End Sub
Public Function ReadFromFileSystem(ByVal FileName As String) As Byte()
Using FileStream As New IO.FileStream(FileName, IO.FileMode.Open)
Using BinaryReader As New IO.BinaryReader(FileStream)
Return BinaryReader.ReadBytes(CInt(FileStream.Length))
End Using
End Using
End Function
End Module
Public Class ConcatenatedDocument
Public PageCount As Integer
Public Document As Byte()
Public Sub New()
PageCount = 0
Document = Nothing
End Sub
Public Sub New(ByVal PageCount As Integer, ByVal Document As Byte())
Me.PageCount = PageCount
Me.Document = Document
End Sub
End Class
Hi Gray,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thank you for sharing the sample code.
I am able to generate your mentioned issue using your sample code. Your issue has been registered in our issue tracking system with issue id: PDFNEWNET-33372. You will be notified via this forum thread regarding any updates against this issue.
Sorry for the inconvenience,
Hi, we solved it temporarly, since we need the fix in 6.8 for some pdf-a issues, by sending in a memorystream of the document instead of a Apose.Pdf.Document in our "concatenate"-metod:
Initial code (with exception 6.8):
var mergedPdf = new Aspose.Pdf.Document();
... Settings some initial metadata
...Foreach PdfQueItem
var success = TryMergeQueItemToPdf(pdfQueItem, mergedPdf)
...Save result
private Boolean TryMergeQueItemToPdf(PdfQueItem pdfQueItem, Aspose.Pdf.Document mergePdf) {
... Loading filestream based on pdfQueItem
var pdfDoc = new Aspose.Pdf.Document(streamPdf);
mergedPDf.Pages.Add(pdfDoc.Pages);
... Disposing streamPdf etc
}
Modified code (working code 6.8):
var streamMergedPdf = new MemoryStream();
using (var mergedPdf = new Aspose.Pdf.Document())
{
... Settings some initial metadata
mergedPdf.Save(streamMergedPdf);
}
...Foreach PdfQueItem
var success = TryMergeQueItemToPdf(pdfQueItem, streamMergedPdf)
...Save result
private Boolean TryMergeQueItemToPdf(PdfQueItem pdfQueItem, MemoryStream streamMergedPdf) {
... Loading filestream based on pdfQueItem
var pdfDoc = new Aspose.Pdf.Document(streamPdf);
using (var mergedPDf = new Aspose.Pdf.Document(streamMergedPdf))
{
mergedPDf.Pages.Add(pdfDoc.Pages);
mergedPDf.Save();
}
... Disposing streamPdf etc
}
Performance-wise is this a bad temporary solution?
Hi Megnus,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
I am glad to know that you are able to temporarily resolve your issue. Now, regarding your performance question, I think as per your implementation, it will affect the performance a bit as you are loading the files first in memory stream before concatenating them. However, I think the major concern might be the memory consumption. If you have large files then it may consume a lot of memory. Also, regarding this issue, I have asked the development team to share an ETA. I will update you once I get a feedback from there side.
Sorry for the inconvenience,
Has this been fixed yet? Is there an ETA for fixing this (it has been almost 3 months now)?
Hi Gary,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thank you for being patient and sorry for a delayed response.
After further analysis from our development team regarding your issue, they have shared the following feedback. As per your following code,
Using Input As New MemoryStream(p)
CombinedDocument.Pages.Add(New Aspose.Pdf.Document(Input).Pages)
End Using
After "End Using" object "Input As Memory" stream is destroyed which causes this problem. To overcome this, please don't use the "using" directive and please modify your code as mentioned below:
Public Function Concatenate(ByRef Pages As List(Of Byte())) As ConcatenatedDocument
Using CombinedDocument As New Aspose.Pdf.Document()
For Each p As Byte() In Pages
Dim Input As New MemoryStream(p)
CombinedDocument.Pages.Add(New Aspose.Pdf.Document(Input).Pages)
Next
CombinedDocument.Save("FinalMerged.pdf")
End Using
End Function
I have tested the above code with the latest version of Aspose.Pdf for .NET v7.0 and it works fine. Please try it and let us know if you still face any issue.
Sorry for the inconvenience,