【问题标题】:split huge 40000 page pdf into single pages, itextsharp, outofmemoryexception将巨大的 40000 页 pdf 拆分为单页,itextsharp,outofmemoryexception
【发布时间】:2011-10-23 09:06:57
【问题描述】:

我正在获取包含大量数据的巨大 PDF 文件。当前的 PDF 为 350 MB,大约有 40000 页。获得更小的 PDF 当然会很好,但这是我现在必须使用的 :-(

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

现在我需要将大文件拆分成单个页面,然后尝试从 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 会更好吗?

【问题讨论】:

  • Wolfram Alpha 表示,双面打印的 40,000 页文档的高度为 80 英寸 - 超过 2m。
  • 只是好奇,这个 PDF 是什么?
  • stackoverflow.com/questions/656351/… 可能有助于尝试另一个或两个库,看看是否有更好的读取属性。
  • @Cicada:这可能是美国税法! :P
  • 这是一组小型公用事业公司的发票。

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


【解决方案1】:

这完全是在黑暗中拍摄的,我还没有测试过这段代码——它是从“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】:

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

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

    【讨论】:

      【解决方案3】:

      根据我的阅读,在实例化 PdfReader 时,您应该使用接受 RandomAccessFileOrArray 对象的构造函数。免责声明:我自己没有尝试过。

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

      【讨论】:

      • 在我刚刚在一个简单的 40,000 页 PDF 上运行的测试中,当使用 PdfReader(string) 构造函数时需要 13.5 秒,而 PdfReader(RandomAccessFileOrArray, Byte[]) 构造函数只需要 2.2 秒(快 6 倍),所以我不得不同意你的建议。
      • 这解决了问题。我现在可以拆分 PDF。谢谢。
      【解决方案4】:

      PDF Toolkit 对于这些类型的任务非常有用。这么大的文件还没试过。

      【讨论】:

        【解决方案5】:

        使用其他库而不是 itextsharp 会更好吗?

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

        披露:我在 Aspose 担任开发布道师。

        【讨论】:

          猜你喜欢
          • 2021-12-08
          • 2012-09-26
          • 2019-01-26
          • 2016-05-20
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          • 2013-09-16
          • 2023-03-31
          相关资源
          最近更新 更多