2016-02-12 27 views
0

我構建了兩個用於創建PDF電子保修的.Net應用程序。爲了創建PDF,我使用與OpenCart集成的Web API 2.0服務,並且一切正常。爲了填寫pdf,我創建了第二個應用程序 - ASP.NET Web Forms,這裏是鎖定pdf文件的問題。System.IO.IOException:鎖定PDF文件

當我打開一個文件並填寫一些字段時,然後將信息保存到數據庫 - 即可正常運行。但是,如果我想在同一個pdf拋出異常中添加另一個信息:

System.IO.IOException:進程無法訪問文件'... \ AllWarranties \ 2016 \ 2 \ 000077.pdf',因爲它是被另一個進程使用。

這隻發生在應用程序在服務器上!何時在本地機器上沒有問題。我研究並查找過程w3wp.exe在打開應用程序時啓動。如果我殺了這個過程,那麼pdf就解鎖了。我在應用程序調查中將Idle Time-out設置爲1分鐘,但這不是解決方案。

問題是:lock 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(); 

回答

3

你忘了這行:

pdfReader.Close(); 

執行此操作時,文件被釋放。如果你忽略這個,文件也可以被髮布,但是很難預測何時。顯然,該文件在本地計算機上快速發佈;但它會在服務器上保持較長時間的打開狀態。

我也不明白你的代碼如何在沒有關閉PdfStamper實例的情況下工作。你不應該處置pdfStamper前加入這一行:

pdfStamper.Close(); 

也許這行不是絕對必要(這將是iText的Java版本的必要),但它不會傷害添加它。

更新:你指的是這個過程被稱爲的w3wp.exeWhat is w3wp.exe?

一個Internet Information Services(IIS)工作進程是Windows進程(W3wp.exe),它運行的Web應用程序,並負責處理髮送到Web服務器的特定的應用程序池的請求。

對於iTextSharp而言,您的磁盤上有一個文件,但該文件被您的Web服務器(IIS)鎖定。爲什麼你將文件存儲在磁盤上?如果將文件保存在內存中,您是不是可以避免這個問題?我不知道你的應用程序的完整過程,所以我不能回答問題的這一部分。

+0

我將文件存儲在磁盤上,因爲這是客戶端需要的功能。我不知道你的意思是將文件保存在內存中 - 也許存儲在會話中,然後存儲到磁盤,或者什麼?今天,我測試了應用程序,並且在對一個pdf進行更改時,然後對另一個進行更改,然後第一個發佈,我可以再次進行更改。再次感謝你的幫助! – dondomates

+1

您將PDF寫入'FileStream'。當我說「將文件保存在內存中」時,我的意思是您也可以將PDF寫入「MemoryStream」。然後你可以使用內存中的字節(1)將它們發送給最終用戶,(2)將它們加載到'PdfReader'中以更改文件,(3)將字節存儲到磁盤中的文件中。 –

+0

我用'MemoryStream'改變了我的代碼,但我不知道是否合適。然而,現在我得到'File.WriteAllBytes(pdfDirectory,pdfContent);'當我第二次去改變字段。我錯在哪裏?在某些特定點或所有解決方案是錯誤的? – dondomates