简体   繁体   English

System.IO.IOException:锁定PDF文件

[英]System.IO.IOException: lock PDF file

I build two .Net applications for create pdf e-warranty. 我构建了两个.NET应用程序来创建pdf电子保修。 For create a pdf I use Web API 2.0 service integrated with OpenCart and everything is OK. 为了创建pdf,我使用与OpenCart集成的Web API 2.0服务,一切正常。 For fill the pdf I create the second app - ASP.NET Web Forms and here is the problem with locking pdf file. 为了填充pdf,我创建了第二个应用程序-ASP.NET Web窗体,这是锁定pdf文件的问题。

When once I open a file and fill some fields, then save the information to DB - everithing is OK. 一旦我打开一个文件并填写一些字段,然后将信息保存到DB-一切正常。 But if I want to add another information on the same pdf throw exception: 但是,如果我想在同一pdf抛出异常上添加其他信息:

System.IO.IOException: The process cannot access the file '...\\AllWarranties\\2016\\2\\000077.pdf' because it is being used by another process. System.IO.IOException:进程无法访问文件'... \\ AllWarranties \\ 2016 \\ 2 \\ 000077.pdf',因为该文件正在由另一个进程使用。

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. 我研究发现打开应用程序时启动了w3wp.exe进程。 If I kill this process, then the pdf is unlocked. 如果我取消了此过程,则pdf将被解锁。 I set Idle Time-out for 1 min on the application poll, but this is not the solution. 我在应用程序轮询中将“空闲超时”设置为1分钟,但这不是解决方案。

And the question is: where is the problem with lock pdf? 问题是:pdf锁定问题在哪里? Is in the process or in me? 是在进行还是在进行中? Maybe I don't close some thing. 也许我没有关闭任何东西。

I use iTextSharp for fill the pdf. 我使用iTextSharp填充pdf。

Edit code with MemoryStream : 使用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. 我也不了解您的代码如何在不关闭PdfStamper实例的情况下工作。 Shouldn't you add this line before disposing pdfStamper : 在处置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. 也许这行不是严格必需的(在iText的Java版本中是必需的),但是添加它并不有害。

Update: you are referring to a process called w3wp.exe . 更新:您指的是名为w3wp.exe的进程。 What is w3wp.exe? 什么是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. Internet信息服务(IIS)工作进程是Windows进程(w3wp.exe),它运行Web应用程序,并负责处理针对特定应用程序池发送到Web服务器的请求。

You have a file on disk that is released as far as iTextSharp is concerned, but that is locked by your web server (IIS). 磁盘上有一个文件,它就iTextSharp而言已发布,但已被Web服务器(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. 我不知道您申请的完整过程,所以我无法回答问题的那一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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