Search code examples
c#itextcode-analysisidisposable

Is PdfStamper disposing output stream? (iTextSharp)


I am using iTextSharp to add page numbers to a PDF with C#. While running code analysis the MemoryStream for the output is suspected to be disposed more than once. See this warning generated by Visual Studio. Is this an API problem? Should the second parameter of PdfStamper be marked as out? Is there a way for me to fix this warning?

MemoryStream mem = null;
PdfReader reader = null;
PdfStamper stamper = null;
try
{
    mem = new MemoryStream();
    reader = new PdfReader(m_pdf);                
    stamper = new PdfStamper(reader, mem);

    // do stuff
    stamper.Close();
    var result = mem.ToArray();
}
finally
{
    if(stamper != null)
    {
        stamper.Dispose();
    }

    if (reader != null)
    {
        reader.Dispose();
    }

    if (mem != null)
    {
        mem.Dispose();
    }
}

Solution

  • This isn't really an answer but to expand upon what @mkl said, switch over to using directives since those perform the try/finally stuff for you automatically.

    Below is the way I (and probably everyone else that uses iTextSharp) would generally recommend to interact with iTextSharp. The outer using is BCL stuff, in this case the MemoryStream and the inner using statements are iTextSharp stuff.

    //Will hold our raw PDF bytes
    Byte[] result;
    
    //BCL stuff first
    using (var mem = new MemoryStream()) {
    
        //iText stuff in the middle
        using (var reader = new PdfReader(m_pdf)) {
            using (var stamper = new PdfStamper(reader, mem)) {
                // do stuff
    
            }
        }
    
        //iText is completely done and disposed of at this point
        //so we can now grab the raw bytes that represent a PDF
        result = mem.ToArray();
    }
    

    As an aside, not necessarily for the OP but just in case someone else sees this, there is almost never (and by "almost never" I really mean "never") a good reason to not close the underlying stream. You can read from the stream by grabbing the raw bytes and writing to it again never makes sense.