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

合并多PDF至单页生成样册时遇System.ObjectDisposedException问题求助

解决iTextSharp合并PDF时的System.ObjectDisposedException错误

问题描述

尝试将多个PDF文件合并为单个PDF文档生成样册,使用基于iTextSharp的C#代码运行时抛出错误:

System.ObjectDisposedException: Cannot access a closed file.

原代码如下:

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CutAndPaste
{
    class Program
    {
        public static readonly string SRC = Environment.CurrentDirectory + "\\pdfs\\2.pdf";
        public static readonly string SRC2 = Environment.CurrentDirectory + "\\pdfs\\3.pdf";
        public static readonly string DEST = Environment.CurrentDirectory + "\\output.pdf";

        static void Main(string[] args)
        {
            MergePDFs(DEST, SRC, SRC2);
            Console.WriteLine("PDF'ler başarıyla birleştirildi.");
        }

        static void MergePDFs(string destPath, params string[] sourcePaths)
        {
            using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.Write, FileShare.None))
            using (Document doc = new Document())
            using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
            {
                doc.Open();
                PdfContentByte cb = writer.DirectContent;

                foreach (string sourcePath in sourcePaths)
                {
                    using (PdfReader reader = new PdfReader(sourcePath))
                    {
                        for (int pageNumber = 1; pageNumber <= reader.NumberOfPages; pageNumber++)
                        {
                            doc.NewPage();
                            PdfImportedPage page = writer.GetImportedPage(reader, pageNumber);
                            cb.AddTemplate(page, 0, 0);
                        }
                    }
                }
            }
        }
    }
}

问题分析

原实现方式存在两个核心问题:

  1. 错误的合并方式:使用PdfWriter+AddTemplate并非iTextSharp合并PDF的标准方案,该方式是将原页面作为模板绘制到新页面,资源管理逻辑复杂。
  2. 资源释放顺序错误:循环内的PdfReader被using块包裹,处理完当前PDF页面后立即释放,但PdfWriter的写入操作是缓冲式的,后续写入时仍会依赖已释放的PdfReader资源,从而触发ObjectDisposedException。

修复方案

使用iTextSharp专门用于PDF合并的PdfCopy类,该类会自动处理资源管理和页面复制逻辑,避免上述问题。修复后的代码如下:

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CutAndPaste
{
    class Program
    {
        // 使用Path.Combine替代字符串拼接,提升路径安全性与跨平台兼容性
        public static readonly string SRC = Path.Combine(Environment.CurrentDirectory, "pdfs", "2.pdf");
        public static readonly string SRC2 = Path.Combine(Environment.CurrentDirectory, "pdfs", "3.pdf");
        public static readonly string DEST = Path.Combine(Environment.CurrentDirectory, "output.pdf");

        static void Main(string[] args)
        {
            MergePDFs(DEST, SRC, SRC2);
            Console.WriteLine("PDF'ler başarıyla birleştirildi.");
        }

        static void MergePDFs(string destPath, params string[] sourcePaths)
        {
            using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.Write, FileShare.None))
            using (Document doc = new Document())
            // 用PdfCopy替换PdfWriter,专门处理PDF合并场景
            using (PdfCopy copy = new PdfCopy(doc, fs))
            {
                doc.Open();
                foreach (string sourcePath in sourcePaths)
                {
                    using (PdfReader reader = new PdfReader(sourcePath))
                    {
                        for (int pageNumber = 1; pageNumber <= reader.NumberOfPages; pageNumber++)
                        {
                            // 获取原页面尺寸,确保目标页面与原页面尺寸一致
                            Rectangle pageSize = reader.GetPageSize(pageNumber);
                            doc.SetPageSize(pageSize);
                            doc.NewPage();
                            // 复制原页面到目标PDF
                            copy.AddPage(copy.GetImportedPage(reader, pageNumber));
                        }
                    }
                }
            }
        }
    }
}

关键改动说明

  • 替换合并工具类:PdfCopy是iTextSharp为PDF合并场景设计的类,内部已优化资源管理逻辑,避免缓冲写入时的资源访问问题。
  • 页面尺寸适配:读取原页面的尺寸并设置为目标文档的当前页面尺寸,避免出现页面布局错乱。
  • 路径优化:使用Path.Combine替代硬编码的字符串拼接,提升代码的可维护性与跨平台兼容性。

内容的提问来源于stack exchange,提问作者Zafer AKKÖSE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:51:17