简体   繁体   中英

System.IO.IOException: lock PDF file

I build two .Net applications for create pdf e-warranty. For create a pdf I use Web API 2.0 service integrated with OpenCart and everything is OK. For fill the pdf I create the second app - ASP.NET Web Forms and here is the problem with locking pdf file.

When once I open a file and fill some fields, then save the information to DB - everithing is OK. But if I want to add another information on the same pdf throw exception:

System.IO.IOException: The process cannot access the file '...\\AllWarranties\\2016\\2\\000077.pdf' because it is being used by another process.

This happen only when app is on server! When is on local machine there has no problem. I research and find the process w3wp.exe start when open the app. If I kill this process, then the pdf is unlocked. I set Idle Time-out for 1 min on the application poll, but this is not the solution.

And the question is: where is the problem with lock pdf? Is in the process or in me? Maybe I don't close some thing.

I use iTextSharp for fill the pdf.

Edit code with MemoryStream :

        string pdfDirectory = @"C:\Projects\Amco\EWarranty\EWarranty" + currentFilePath.FilePath;

        MemoryStream inputMemoryStream = new MemoryStream();

        using (FileStream fs = File.OpenRead(pdfDirectory))
        {
            inputMemoryStream.SetLength(fs.Length);
            fs.Read(inputMemoryStream.GetBuffer(), 0, (int)fs.Length);
            inputMemoryStream.Seek(0, SeekOrigin.Begin);
        }

        PdfReader pdfReader = new PdfReader(inputMemoryStream);

        using (Stream inputImageStream = new FileStream(@"C:\Projects\Amco\EWarranty\pechatAMCO.png", FileMode.Open, FileAccess.Read, FileShare.Read))
        using (MemoryStream outputStream = new MemoryStream())
        {
            using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
            {
                if (currentServiceMap.FailureNumber == 0)
                {
                    var pdfContentByte = pdfStamper.GetOverContent(3);

                    Image image = Image.GetInstance(inputImageStream);
                    image.ScaleToFit(150, 150);
                    image.SetAbsolutePosition(140, 425);
                    pdfContentByte.AddImage(image);
                }

                // Some other else if statements ...

                AcroFields pdfFormFields = pdfStamper.AcroFields;

                BaseFont cyrillicFont = BaseFont.CreateFont(@"C:\Windows\Fonts\Arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

                pdfFormFields.AddSubstitutionFont(cyrillicFont);

                // first fail
                if (txt_First_Adoption_Date.Text != "")
                {
                    pdfFormFields.SetField("firstAdoptionDate", txt_First_Adoption_Date.Text);
                }

                if (txt_First_Failure.Text != "")
                {
                    pdfFormFields.SetField("firstFailure", txt_First_Failure.Text);
                }

                if (txt_First_Return_Date.Text != "")
                {
                    pdfFormFields.SetField("firstReturnDate", txt_First_Return_Date.Text);
                }

                // Second, third and so on failds ...

                warrantyService.UpdateServiceMapByAdmin(CurrentSessions.warrantyNumber, txt_First_Adoption_Date.Text, txt_First_Failure.Text, "", txt_First_Return_Date.Text, txt_Second_Adoption_Date.Text, txt_Second_Failure.Text,
                                                            "", txt_Second_Return_Date.Text, txt_Third_Adoption_Date.Text, txt_Third_Failure.Text, "", txt_Third_Return_Date.Text, txt_Fourth_Adoption_Date.Text, txt_Fourth_Failure.Text,
                                                            "", txt_Fourth_Return_Date.Text, txt_Fifth_Adoption_Date.Text, txt_Fifth_Failure.Text, "", txt_Fifth_Return_Date.Text, (currentServiceMap.FailureNumber + 1));

                pdfStamper.FormFlattening = false;
            }

            byte[] pdfContent = outputStream.ToArray();

            File.WriteAllBytes(pdfDirectory, pdfContent);
        }

        pdfReader.Close();

        inputMemoryStream.Close();

You forgot this line:

pdfReader.Close();

When you do this, the file is released. If you omit this, the file can be released too, but it's hard to predict when. Apparently, the file is released quickly on your local machine; but it remains open for a longer time on your server.

I also don't understand how your code can work without closing the PdfStamper instance. Shouldn't you add this line before disposing pdfStamper :

pdfStamper.Close();

Maybe this line isn't strictly necessary (it would be necessary in the Java version of iText), but it doesn't hurt to add it.

Update: you are referring to a process called w3wp.exe . What is w3wp.exe?

An Internet Information Services (IIS) worker process is a windows process (w3wp.exe) which runs Web applications, and is responsible for handling requests sent to a Web Server for a specific application pool.

You have a file on disk that is released as far as iTextSharp is concerned, but that is locked by your web server (IIS). Why do you store the file on disk? Wouldn't you avoid this problem if you kept the file in memory? I don't know the complete process of your application, so I can't answer that part of the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM