0
votes

Have a PDF on disk that is 498kb. I'm reading this into a MemoryStream which reports the size as 508978 when viewed in the debugger. Then using a reader and stamper, the output MemoryStream has a size of 15. When the stream is output to disk the PDF is unreadable.

MemoryStream inputStream = new MemoryStream();
MemoryStream outputStream = new MemoryStream();

FileStream fs = File.OpenRead(@"e:\O1.pdf");           
inputStream.SetLength(fs.Length);
fs.Read(inputStream.GetBuffer(), 0, (int)fs.Length);
inputStream.Seek(0, SeekOrigin.Begin);


PdfReader reader = new PdfReader(inputStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.Writer.CloseStream = false;


AcroFields fields = reader.AcroFields;
foreach (String key in fields.Fields.Keys)
{
if (String.Equals(key, @"ReportID")) { stamper.AcroFields.SetField(@"ReportID", "Fred Bloggs");   }
}

stamper.Close();
Byte[] bytes = (Byte[])outputStream.ToArray();
File.WriteAllBytes(@"e:\O2.pdf", bytes);
1
1) The source of ConvertFileToStream() is missing. 2) You compute the length of the output stream before doing anything with the stamper; look at the length after stamping and closing the stamper; you may need stamper.CloseStream = false. - mkl
Taking into account your edit: Yes, your code definitively misses a stamper.Close() call or a using construct implicitly causing Close to be called. As you lateron try to use outputStream as a stream, you need to set stamper.CloseStream = false before that. - mkl
@mkl - Not understanding you here. You say I'm missing a stamper.Close() which I get, however then you say I need a stamper.CloseStream=false before that. Is this Java syntax as it does not exist in C#. - Dave
Sorry. No, it's not Java, it's .Net only, but the CloseStream property is not directly in the PdfStamper but in its associated writer; thus, you will want to do stamper.Writer.CloseStream = false... - mkl

1 Answers

3
votes

Your code snippet is incomplete, which makes it hard to answer your question.

You make people guess your question.

First guess:

You have a PDF of 10 KB, when reading it with PdfReader, you suddenly use 100 KB. You are surprised. How can this be?

The answer is simple: the PDF of 10 KB is compressed. When PdfReader starts working with it, it creates objects (requiring memory) and it decompresses data (requires more memory).

Second guess:

You have a PdfReader object and you use it to create a PdfStamper object. You forget to close the stamper. Suddenly you have a very small file of which PDF viewer tell you: this isn't a real PDF. How come?

You've made a mistake that many people who don't read the documentation make. The file you're manipulating with PdfStamper isn't fully written until you close the stamper.

Third guess:

You have a PdfReader object and you use it to create a PdfStamper object. You don't do anything with the stamper, you just close it. You're surprised the resulting PDF has a different size than the original one.

  • The size is smaller: iText sometimes throws away unused object, and it reorders objects in different ways. This is typical for PDF libraries.
  • The size is bigger: even if you didn't add anything, file size can grow, for instance when the original document is fully compressed (PDF 1.5 and higher). By default, PdfStamper won't create a compressed xref-stream (unless you instruct PdfStamper to compress the xref).

If none of these answers apply, I suggest that you rephrase your question. If not, you'll risk that moderators close it.