我为创建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();
答案 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)已将其锁定。为什么要将文件存储在磁盘上?如果将文件保存在内存中,你不会避免这个问题吗?我不知道申请的完整过程,所以我无法回答问题的这一部分。