PDFsharp & MigraDoc Forum

PDFsharp - A .NET library for processing PDF & MigraDoc - Creating documents on the fly
It is currently Fri Apr 18, 2025 9:36 am

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules

Also see our new Tailored Support & Services site.



Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
PostPosted: Wed Apr 02, 2025 4:10 pm 
Offline

Joined: Wed Apr 02, 2025 3:37 pm
Posts: 1
Affected Version
itext7 (9.1.0) and itext7.bouncy-castle-adapter (9.1.0) via NuGet on Windows 11.

Actual Behavior
At present, PdfWriter takes in a Stream for output and it closes that stream when finished. If the provided stream is a FileStream and the user wants the stream to be closed when PdfWriter is finished then there's no problem.

Why It's Bad
If the provided stream is a MemoryStream or something else instead of a FileStream and if the user wants the stream to stay open (such as if providing the contents of the PDF to the browser in a Blazor or other web application or if some additional encryption or compression needs to be applied to the stream before closing) then closing the stream in that case is very bad. When a MemoryStream is closed, it contents are just thrown away by the garbage collector so that they can no longer be used by the program. This makes PdfWriter incompatible with (directly) using MemoryStream for output: a common and very desirable use case because we don't want to engage our storage device whenever doing the operation in RAM instead would suffice.

Expected Behavior
PdfWriter should have a boolean leaveOpen parameter with a default value of false in its constructor and then only close the stream in the case that leaveOpen is false. This is common practice for handling streams in C#, for example in BinaryWriter. It would fix the issue while not breaking any existing user code due to leaveOpen's default value reflecting the current behavior.

That way, when using PdfWriter, my code would look like this:
Code:
using PdfWriter writer = new(os: outputStream, leaveOpen: true);

If I wanted the stream closed then I could just not specify leaveOpen.

Another option might be to include leaveOpen in the WriterProperties class instead, but this would not be following the common practice for stream handling in C# so users might have trouble finding it in there. I certainly don't see anything about leaving the stream open when looking at WriterProperties right now.

PdfReader may also benefit from a similar change if it is closing its input stream although I haven't personally tested to find out whether it has such an issue.

A Workaround
This is what I'm actually doing to work around this issue at present. I have an entire class which exists only to take the ability to close the stream away from PdfWriter by ignoring its command to close the stream:
Code:
public class NonClosingStreamWrapper(Stream innerStream) : Stream
{
      public override void Close() { }
      protected override void Dispose(bool disposing) { }
      public override bool CanRead => innerStream.CanRead;
      public override bool CanSeek => innerStream.CanSeek;
      public override bool CanWrite => innerStream.CanWrite;
      public override long Length => innerStream.Length;
      public override long Position
      {
            get => innerStream.Position;
            set => innerStream.Position = value;
      }
      public override void Flush() => innerStream.Flush();
      public override int Read(byte[] buffer, int offset, int count) => innerStream.Read(buffer, offset, count);
      public override long Seek(long offset, SeekOrigin origin) => innerStream.Seek(offset, origin);
      public override void SetLength(long value) => innerStream.SetLength(value);
      public override void Write(byte[] buffer, int offset, int count) => innerStream.Write(buffer, offset, count);
}

I then use it like this:
Code:
using PdfWriter writer = new(new NonClosingStreamWrapper(outputStream));

This works, but I shouldn't have to do this because PdfWriter should handle its stream properly with a boolean leaveOpen parameter as is common practice in C#.

I believe this issue should be trivial to fix but please let me know if there's any way I can help. Thanks for considering this issue.


Top
 Profile  
 
PostPosted: Thu Apr 03, 2025 6:19 am 
Offline
PDFsharp Expert
User avatar

Joined: Wed Dec 09, 2009 8:59 am
Posts: 351
BenMcLean wrote:
Affected Version
itext7 (9.1.0) and itext7.bouncy-castle-adapter (9.1.0) via NuGet on Windows 11.
Welcome to the PDFsharp forum.

_________________
Öhmesh Volta ("() => true")
PDFsharp Team Holiday Substitute


Top
 Profile  
 
PostPosted: Sun Apr 06, 2025 1:33 pm 
Offline
PDFsharp Guru
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 1040
Location: CCAA
The PdfWriter class has a parameter that controls whether the underlying stream will be closed automatically.

But the transition from itext to PDFsharp is not trivial.
PDFsharp comes under the MIT license.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group