System.IO.IOException:锁定PDF文件

时间:2016-02-12 11:59:51

标签: c# asp.net pdf itextsharp

我为创建pdf电子保修构建了两个.Net应用程序。为了创建一个pdf,我使用与OpenCart集成的Web API 2.0服务,一切正常。为了填写pdf,我创建了第二个应用程序 - ASP.NET Web Forms,这是锁定pdf文件的问题。

当我打开文件并填写一些字段时,然后将信息保存到数据库中 - 永远可以。但是如果我想在同一个pdf throw异常中添加另一个信息:

System.IO.IOException:进程无法访问文件' ... \ AllWarranties \ 2016 \ 2 \ 000077.pdf'因为它正被另一个进程使用。

仅当app在服务器上时才会发生这种情况!何时在本地机器上没有问题。我研究并发现打开应用程序时启动 w3wp.exe 的过程。如果我终止了这个过程,那么pdf就会被解锁。我在应用程序轮询中将Idle Time-out设置为1分钟,但这不是解决方案。

问题是:锁定pdf的问题在哪里?是在过程中还是在我身上?也许我不会关闭一些东西。

我使用 iTextSharp 填写pdf。

使用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();

1 个答案:

答案 0 :(得分:3)

你忘了这句话:

pdfReader.Close();

执行此操作时,文件将被释放。如果省略这个,那么文件也可以被释放,但很难预测何时。显然,该文件在本地计算机上快速发布;但它在服务器上保持打开的时间较长。

我也不了解您的代码如何在不关闭PdfStamper实例的情况下工作。在处置pdfStamper之前,不应该添加此行:

pdfStamper.Close();

也许这条线不是必须的(在iText的Java版本中是必要的),但添加它并不会有什么坏处。

更新:您指的是名为 w3wp.exe 的进程。 What is w3wp.exe?

  

Internet信息服务(IIS)工作进程是一个运行Web应用程序的Windows进程(w3wp.exe),负责处理发送到特定应用程序池的Web服务器的请求。

就iTextSharp而言,您在磁盘上有一个文件,但是您的Web服务器(IIS)已将其锁定。为什么要将文件存储在磁盘上?如果将文件保存在内存中,你不会避免这个问题吗?我不知道申请的完整过程,所以我无法回答问题的这一部分。