1

I'm generating a pdf file from a template with iTextSharp, filling each field in this code portion:

        PdfReader pdfReader = new PdfReader(templatePath);
        try
        {
            using (FileStream newFileStream = new FileStream(newFilePath, FileMode.Create))
            {
                using (PdfStamper stamper = new PdfStamper(pdfReader, newFileStream))
                {
                    // fill each field
                    AcroFields pdfFormFields = stamper.AcroFields;
                    foreach (KeyValuePair<string, string> entry in content)
                    {
                        if (!String.IsNullOrEmpty(entry.Value))
                            pdfFormFields.SetField(entry.Key, entry.Value);
                    }

                    //The below will make sure the fields are not editable in
                    //the output PDF.
                    stamper.FormFlattening = true;
                    stamper.Close();
                }                    
            }
        }
        finally
        {
            pdfReader.Close();
        }

Everything goes fine, file looks ok, but when i try to reopen the file to merge it with some other files I've generated in a unique document i get this error:

2015-11-23 09:46:54,651||ERROR|UrbeWeb|System.IO.IOException: The process cannot access the file 'D:\Sviluppo\communitygov\MaxiAnagrafeImmobiliare\MaxiAnagrafeImmobiliare\cache\IMU\E124\admin\Stampe\Provvedimento_00223850306_2015_11_23_094654.pdf' because it is being used by another process.

Error occurs at this point

foreach (Documento item in docs)
{                                      
           string fileName = item.FilePath;
           pdfReader = new PdfReader(fileName); // IOException
           // some other operations ...                    
}

Edit: Using Process monitor as suggested I can see there is no close CloseFile operation as I would expect. Can this be the source of the issue?

I've been stuck on this for hours any help is really really appreciated.

LNyarla
  • 454
  • 1
  • 8
  • 23
  • 2
    Possible duplicate of [Cannot access the file because it is being used by another process](http://stackoverflow.com/questions/15617883/cannot-access-the-file-because-it-is-being-used-by-another-process) – MusicLovingIndianGirl Nov 23 '15 at 10:49
  • 2
    have you tried to debug with source code (they are available)? Ot look at file handles with FileMon? – Lonli-Lokli Nov 23 '15 at 10:50
  • 1
    Do you have any of the PDF files open in e.g. Adobe Reader ? Some applications lock a file for editing when opening it. – blagae Nov 23 '15 at 10:51
  • 1
    another small point: you close `stamper` and `pdfReader` but you don't close `newFileStream`. `using` should dispose of it anyway so it might not make any difference... – roryok Nov 23 '15 at 10:53
  • @blagae I don't have any application such Adobe Reader open. – LNyarla Nov 23 '15 at 11:13
  • Is it possible that there is an exception occuring on flattening of the stamper? Which prevents the stamper to be closed – misha130 Nov 23 '15 at 11:43
  • @misha130 The `using` directives should take care of that – mkl Nov 23 '15 at 11:57
  • 1
    So why write stamper.Close() at all? Also for the sake of testing maybe save the PdfStamper in to a MemoryStream and then use it when you are merging. – misha130 Nov 23 '15 at 12:02
  • Are you sure that while iterating over `docs`, all of those docs have already been created? Or might one of them still be in the process of being created in a separate thread? – mkl Nov 23 '15 at 12:02
  • @misha130 *So why write stamper.Close() at all* - Indeed it is not necessary here at the end of that `using` block. *Also for the sake of testing maybe save the PdfStamper in to a MemoryStream and then use it when you are merging.* - Definitively worth a try. – mkl Nov 23 '15 at 12:04
  • I think problem in your 'docs' - you have loaded files in memory, then trying to open them one more time. With this snippet I havo no problem, try to reproduce with it first http://pastebin.com/t9NcvfAL – Lonli-Lokli Nov 23 '15 at 13:23
  • @misha130 save the PdfStamper in to a MemoryStream sounds as a good suggestion but PdfStamper is not serializable. – LNyarla Nov 23 '15 at 13:57
  • 2
    @LNyarla, `PdfStamper` can bind to any subclass of `Stream`, so what mkl meant was to use a `MemoryStream` instead of a `FileStream` and just grab the PDF as a byte array using `ToArray()` on the `MemoryStream`. Also, you'll see that `Close()` is called often but as you pointed out and mkl responded it is not needed. This is just an artifact (that I always do) of the "If you open something you should close it" mentality but you can skip it. – Chris Haas Nov 23 '15 at 15:11

2 Answers2

5

Had the same issue with me. This helped a lot.

"You're problem is that you are writing to a file while you are also reading from it. Unlike some file types (JPG, PNG, etc) that "load" all of the data into memory, iTextSharp reads the data as a stream. You either need to use two files and swap them at the end or you can force iTextSharp to "load" the first file by binding your PdfReader to a byte array of the file."

PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath));

Ref: Cris Haas answer to Cannot access the file because it is being used by another process

Community
  • 1
  • 1
Mahatma Aladdin
  • 2,027
  • 3
  • 17
  • 31
0

I had a similar problem with opening pdf files (for read only) with iTextSharp PdfReader. The first file gave no problem, the second one gave that exception (can not access the file, etc.). After hours and googling and searching for complicate solutions and twisting my brain, only the simple following code resolved it fully:

iTextSharp_pdf.PdfReader pdfReader = null;
pdfReader = new iTextSharp_pdf.PdfReader(fileName);