iTextSharp Pdf页面导入内存问题

问题描述

| 我正在使用此代码将不同的pdf文件页面导入单个文档。导入大文件(200页或以上)时,出现“ 0”例外。我在这里做错什么了吗?
    private bool SavetoFile(string fileName)
    {
        try
        {
            iTextSharp.text.Document doc;
            iTextSharp.text.pdf.Pdfcopy pdfcpy;
            string output = fileName;

            doc = new iTextSharp.text.Document();
            pdfcpy = new iTextSharp.text.pdf.Pdfcopy(doc,new System.IO.FileStream(output,System.IO.FileMode.Create));
            doc.open();

            foreach (DataGridViewRow item in dvSourcePreview.Rows)
            {
                string pdfFileName = item.Cells[COL_FILENAME].Value.ToString();
                int pdfpageIndex = int.Parse(item.Cells[COL_PAGE_NO].Value.ToString());
                pdfpageIndex += 1;

                iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(pdfFileName);
                int pageCount = reader.NumberOfPages;

                // set page size for the documents
                doc.SetPageSize(reader.GetPageSizeWithRotation(1));

                iTextSharp.text.pdf.PdfImportedPage page = pdfcpy.GetImportedPage(reader,pdfpageIndex);
                pdfcpy.AddPage(page);

                reader.Close();
            }

            doc.Close();

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
    

解决方法

        您正在为每个通行证创建一个新的
PdfReader
。那真是低效。而且由于每个对象都有一个
PdfImportedPage
,所以所有这些(可能是冗余的)
PdfReader
实例都不会进行GC处理。 意见建议: 两遍。首先建立文件和页面列表。其次,依次对每个文件进行操作,因此一次只能有一个
PdfReader
\“ open \”。完成给定阅读器的使用后,请使用ѭ6。这几乎可以肯定会改变页面添加的顺序(也许很不好)。 一通。根据文件名缓存“ 2”个实例。完成操作后,再次使用FreeReader ...,但是您可能无法释放其中的任何一个,除非退出循环。单独的缓存可能足以使您避免内存不足。 保持代码不变,但是在关闭给定的
PdfReader
实例后调用
freeReader()
。     ,        我还没有遇到iTextSharp的OOM问题。 PDF是使用iTextSharp还是其他创建的?您能否将问题隔离到单个PDF或一组可能损坏的PDF?下面是示例代码,该示例代码创建10个PDF,每个PDF包含1,000页。然后,它再创建一个PDF并从这些PDF中随机抽取一页500次。在我的计算机上,它需要一些时间才能运行,但是我看不到任何内存问题或其他任何东西。 (iText 5.1.1.0)
using System;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender,EventArgs e)
        {
            //Folder that we will be working in

            string WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),\"Big File PDF Test\");

            //Base name of PDFs that we will be creating
            string BigFileBase = Path.Combine(WorkingFolder,\"BigFile\");

            //Final combined PDF name
            string CombinedFile = Path.Combine(WorkingFolder,\"Combined.pdf\");

            //Number of \"large\" files to create
            int NumberOfBigFilesToMakes = 10;

            //Number of pages to put in the files
            int NumberOfPagesInBigFile = 1000;

            //Number of pages to insert into combined file
            int NumberOfPagesToInsertIntoCombinedFile = 500;

            //Create our test directory
            if (!Directory.Exists(WorkingFolder)) Directory.CreateDirectory(WorkingFolder);

            //First step,create a bunch of files with a bunch of pages,hopefully code is self-explanatory
            for (int FileCount = 1; FileCount <= NumberOfBigFilesToMakes; FileCount++)
            {
                using (FileStream FS = new FileStream(BigFileBase + FileCount + \".pdf\",FileMode.Create,FileAccess.Write,FileShare.Read))
                {
                    using (iTextSharp.text.Document Doc = new iTextSharp.text.Document(PageSize.LETTER))
                    {
                        using (PdfWriter writer = PdfWriter.GetInstance(Doc,FS))
                        {
                            Doc.Open();
                            for (int I = 1; I <= NumberOfPagesInBigFile; I++)
                            {
                                Doc.NewPage();
                                Doc.Add(new Paragraph(\"This is file \" + FileCount));
                                Doc.Add(new Paragraph(\"This is page \" + I));
                            }
                            Doc.Close();
                        }
                    }
                }
            }

            //Second step,loop around pulling random pages from random files

            //Create our output file
            using (FileStream FS = new FileStream(CombinedFile,FileShare.Read))
            {
                using (Document Doc = new Document())
                {
                    using (PdfCopy pdfCopy = new PdfCopy(Doc,FS))
                    {
                        Doc.Open();

                        //Setup some variables to use in the loop below
                        PdfReader reader = null;
                        PdfImportedPage page = null;
                        int RanFileNum = 0;
                        int RanPageNum = 0;

                        //Standard random number generator
                        Random R = new Random();

                        for (int I = 1; I <= NumberOfPagesToInsertIntoCombinedFile; I++)
                        {
                            //Just to output our current progress
                            Console.WriteLine(I);

                            //Get a random page and file. Remember iText pages are 1-based.
                            RanFileNum = R.Next(1,NumberOfBigFilesToMakes + 1);
                            RanPageNum = R.Next(1,NumberOfPagesInBigFile + 1);

                            //Open the random file
                            reader = new PdfReader(BigFileBase + RanFileNum + \".pdf\");
                            //Set the current page
                            Doc.SetPageSize(reader.GetPageSizeWithRotation(1));

                            //Grab a random page
                            page = pdfCopy.GetImportedPage(reader,RanPageNum);
                            //Add it to the combined file
                            pdfCopy.AddPage(page);

                            //Clean up
                            reader.Close();
                        }

                        //Clean up
                        Doc.Close();
                    }
                }
            }

        }
    }
}