将巨大的40000页pdf分成单页,itextsharp,outofmemoryexception

时间:2011-08-09 16:07:57

标签: c# asp.net pdf itextsharp out-of-memory

我收到包含大量数据的巨大PDF文件。当前的PDF为350 MB,大约有40000页。获得较小的PDF当然很不错,但这就是我现在要处理的事情: - (

我可以在acrobat阅读器中打开它,但在加载时会有一些延迟,但在那之后acrobat阅读器很快。

现在我需要将大文件拆分成单个页面,然后尝试从pdf页面读取一些收件人数据,然后发送每个收件人应该获得的一个或两个页面给每个特定收件人。

到目前为止,这是我使用itextsharp的非常小的代码:

var inFileName = @"huge350MB40000pages.pdf";
PdfReader reader = new PdfReader(inFileName);
var nbrPages = reader.NumberOfPages;
reader.Close();

第二行“new PdfReader”会在那里停留大约10分钟,进程大小达到1.7 GB,然后我得到一个OutOfMemoryException。

我认为“新的PdfReader”试图将整个PDF读入内存。

还有其他/更好的方法吗? 例如,我可以以某种方式只将PDF文件的一部分读入内存而不是一次只读取所有内容吗? 使用除itextsharp以外的其他库可以更好地工作吗?

5 个答案:

答案 0 :(得分:16)

从我读过的内容看,在实例化PdfReader时,您应该使用接收RandomAccessFileOrArray对象的构造函数。免责声明:我自己没有试过这个。

iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(new iTextSharp.text.pdf.RandomAccessFileOrArray(@"C:\PDFFile.pdf"), null);

答案 1 :(得分:4)

这是黑暗中的一个完整镜头,我还没有测试过这段代码 - 它是“iText In Action”一书中的代码摘录,作为如何处理大型PDF文件的示例。代码是用Java编写的,但应该很容易转换 -

这是将所有内容加载到内存中的方法 -

PdfReader reader;
long before;
before = getMemoryUse();
reader = new PdfReader(
"HelloWorldToRead.pdf", null);
System.out.println("Memory used by the full read: "
+ (getMemoryUse() - before));

这是节省内存的方式,应根据需要逐位加载文档 -

before = getMemoryUse();
reader = new PdfReader(
new RandomAccessFileOrArray("HelloWorldToRead.pdf"), null);
System.out.println("Memory used by the partial read: "
+ (getMemoryUse() - before));

答案 2 :(得分:0)

您可以直接使用Ghostscript。 http://svn.ghostscript.com/ghostscript/tags/ghostscript-9.02/doc/Use.htm#One_page_per_file

对于阅读收件人数据,pdftextstream可能是一个不错的选择。

答案 3 :(得分:0)

PDF Toolkit对于这些类型的任务非常有用。尽管如此,还没有尝试过如此庞大的文件。

答案 4 :(得分:0)

  

使用除itextsharp以外的其他库可以更好地工作吗?

请尝试使用Aspose.Pdf for .NET split the PDF into single pages,或者使用文件或内存流以各种方式split the PDF to different sets of pages {{3}}。 API非常易于学习和使用。它适用于具有大量页面的大型PDF文件。

披露:我在Aspose担任开发人员传播者。