You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

释放PdfReader致Document、PdfWriter被释放引发异常的原因及解决

为什么释放PdfReader会导致Document/PdfWriter被意外释放?

问题背景

你在编写合并多个PDF第一页的代码时遇到了一个棘手的问题:用using语句自动释放PdfReader后,执行document.Close()时居然抛出了System.ObjectDisposedException,就好像Document和PdfWriter也被一起销毁了。虽然跳过释放PdfReader能暂时跑通代码,但显然不符合资源管理的最佳实践。

根因解析

这其实是iText库内部的引用关联机制导致的:当你通过writer.GetImportedPage(reader, 1)创建导入页时,PdfWriter会自动持有这个PdfReader的引用。默认情况下,当PdfReader被释放(也就是using块结束时),它会触发关联的PdfWriter释放相关资源——这就直接导致后续操作时,Document和PdfWriter已经处于被销毁的状态了。

解决方案

要解决这个问题,核心是在释放PdfReader之前,先让PdfWriter解除和它的绑定关系。iText提供了writer.FreeReader(reader)方法来做这件事,调用它之后,PdfWriter就不再持有该PdfReader的引用,此时再释放PdfReader就不会影响到Document和PdfWriter了。

修正后的完整代码如下:

using (FileStream fs = new FileStream(Path.Combine(pathPorducedPDFs, "function1.pdf"), FileMode.Create)) 
using (Document document = new Document(PageSize.A2)) 
using (PdfWriter writer = PdfWriter.GetInstance(document, fs)) { 
    document.Open(); 
    PdfContentByte cb = writer.DirectContent; 
    foreach (string pdfPath in Directory.GetFiles(pathOriginalPDFs).OrderBy(x => x).ToList()) { 
        using (PdfReader reader = new PdfReader(pdfPath)) { 
            PdfImportedPage page = writer.GetImportedPage(reader, 1); 
            document.NewPage(); 
            cb.AddTemplate(page, 0, 0); 
            document.Add(new Paragraph(pdfPath)); 
            // 关键步骤:让Writer释放对当前Reader的引用
            writer.FreeReader(reader); 
        } 
    } 
    document.Close(); 
    writer.Close(); 
    fs.Close(); 
}

额外提示

  • 一定要保留using语句管理PdfReader,这是确保临时资源及时释放、避免内存泄漏的关键。
  • FreeReader是iText专门为这种多Reader复用Writer的场景设计的API,能安全清理Writer内部的关联缓存,不会影响后续的PDF生成操作。

内容的提问来源于stack exchange,提问作者Marco Salerno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:38:12