我構建了兩個用於創建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();
我將文件存儲在磁盤上,因爲這是客戶端需要的功能。我不知道你的意思是將文件保存在內存中 - 也許存儲在會話中,然後存儲到磁盤,或者什麼?今天,我測試了應用程序,並且在對一個pdf進行更改時,然後對另一個進行更改,然後第一個發佈,我可以再次進行更改。再次感謝你的幫助! – dondomates
您將PDF寫入'FileStream'。當我說「將文件保存在內存中」時,我的意思是您也可以將PDF寫入「MemoryStream」。然後你可以使用內存中的字節(1)將它們發送給最終用戶,(2)將它們加載到'PdfReader'中以更改文件,(3)將字節存儲到磁盤中的文件中。 –
我用'MemoryStream'改變了我的代碼,但我不知道是否合適。然而,現在我得到'File.WriteAllBytes(pdfDirectory,pdfContent);'當我第二次去改變字段。我錯在哪裏?在某些特定點或所有解決方案是錯誤的? – dondomates