【问题标题】:iTextSharp Created PDF is still in useiTextSharp 创建的 PDF 仍在使用中
【发布时间】:2019-11-01 04:33:00
【问题描述】:

如果我使用给定的源代码创建 pdf,我会遇到无法打开 pdf 文档的问题,例如在“adobe-acrobat”中,因为它说它仍在被另一个进程使用。我的代码中缺少什么来释放锁?

var a = Guid.NewGuid();

Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);

PdfWriter writer2 = PdfWriter.GetInstance(pdfDoc, new FileStream(a.ToString()+".pdf", FileMode.Create));
writer2.SetFullCompression();
writer2.CloseStream = true;

iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(AppContext.BaseDirectory + "Ehrungsantrag.png");
img.SetAbsolutePosition(0, 0);
img.ScaleAbsoluteHeight(pdfDoc.PageSize.Height);
img.ScaleAbsoluteWidth(pdfDoc.PageSize.Width);
pdfDoc.Open();
pdfDoc.NewPage();
pdfDoc.Add(img);

pdfDoc.Close();
writer2.Close();

【问题讨论】:

  • 你确定这段代码可以正常运行吗?如果您收到错误消息,则不会关闭您的流,因为它们不在 using 中。
  • IDisposable 对象应该被关闭和处理
  • @bradbury9 理论上是的,但 PdfWriter 错误地实现了底层模式。

标签: c# asp.net-core-mvc itext


【解决方案1】:

错误未关闭 FileStream。同样正如@Amy 已经提到的,您需要确保执行了您的清理代码,例如:

Document pdfDoc = null;
PdfWriter writer2 = null;
System.IO.FileStream fs = null; // <- create the FileStream

try
{
   var a = Guid.NewGuid();
   pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);

   fs =  new FileStream(a.ToString()+".pdf", FileMode.Create);
   writer2 = PdfWriter.GetInstance(pdfDoc, fs);
   writer2.SetFullCompression();
   writer2.CloseStream = true;

   iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(AppContext.BaseDirectory + "Ehrungsantrag.png");
   img.SetAbsolutePosition(0, 0);
   img.ScaleAbsoluteHeight(pdfDoc.PageSize.Height);
   img.ScaleAbsoluteWidth(pdfDoc.PageSize.Width);

   pdfDoc.Open();
   pdfDoc.NewPage();
   pdfDoc.Add(img);
}
finally
{
        pdfDoc.Close();
        pdfDoc = null;

        //writer2.Close(); 

       // That was the eroor -> always close open filehandles explicity !
       fs.Close(); 
}

【讨论】:

  • 如果我尝试这个提供的解决方案,它不会影响我的问题 - 当我尝试打开 pdf 时仍然出现此错误:'该文件无法打开,因为它正在被另一个进程使用。请关闭所有可能访问此文件的应用程序,然后重试。'
  • 是的,当然 - 没有错误。但是文档在创建过程中仍然像被阻塞一样。
  • 糟糕的异常处理。此外,无需将变量设置为null。最好使用IDisposable 模式。
  • 完全没有必要。永远不要在本地处理,始终在全局处理,或者如果您真的需要在本地处理。
  • 然后删除catch 并留下finally。也让它更清晰。
【解决方案2】:
var a = Guid.NewGuid();

using (var pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f))
using (var writer2 = PdfWriter.GetInstance(pdfDoc, new FileStream(a.ToString()+".pdf", FileMode.Create));
{
    writer2.SetFullCompression();
    writer2.CloseStream = true;

    iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(AppContext.BaseDirectory + "Ehrungsantrag.png");
    img.SetAbsolutePosition(0, 0);
    img.ScaleAbsoluteHeight(pdfDoc.PageSize.Height);
    img.ScaleAbsoluteWidth(pdfDoc.PageSize.Width);
    pdfDoc.Open();
    pdfDoc.NewPage();
    pdfDoc.Add(img);

    pdfDoc.Close();
    writer2.Close()
}

【讨论】:

  • 当使用IDisposable 模式时,不需要那些最后的Close() 调用。
  • 请不要将itext 7之前版本的PdfWriter放到using中。是的,它实现了IDisposable,但错误地如此。根据架构,它预计会被Document 间接关闭(PdfWriter.GetInstance 相应地注入实例)。如果在Document之前关闭,结果pdf中可能会丢失一些内容。
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 2018-12-27
  • 2015-01-01
  • 1970-01-01
相关资源
最近更新 更多