PDFBox 2.0.3 / Java 7 - OOM将页面从一个PDF导入另一个PDF时出错

时间:2017-11-28 21:45:42

标签: java-7 pdfbox

我有一些代码可以检查大型PDF(20,000多页)中的每个页面,如果该页面包含某个字符串,那么它会将该页面导入另一个PDF。

由于出现次数,导入的PDF几乎与源PDF一样大 - 当它变得太大时,它会因以下异常而爆炸:

Exception in thread "main" java.lang.OutofMemoryError: Java heap space
at java.utils.Arrays.copyOf (Unknown Source)
at java.io.ByteArrayOutputStream.toByteArray (Unknown Source)
at org.apache.pdfbox.cos.COSOutputStream.close(COSOutputStream.java:87)
at java.io.FilterOutputStream.close(Unknown Source)
at org.apache.pdfbox.cos.COSStream$1.close(COSStream.java:223)
at org.apache.pdfbox.pdmodel.common.PDStream.<init>(PDStream.java:138)
at org.apache.pdfbox.pdmodel.common.PDStream.<init>(PDStream.java:104)
at org.apache.pdfbox.pdfmodel.PDDocument.importPage(PDDocument.java:562)
at ExtractPage.extractString(ExtractPage.java:57)
at RunApp.run(RunApp.java:15)

我已经研究过这个问题,看起来使用临时文件进行流式传输可以解决我的问题。但是,我无法弄清楚如何将其实现到我的代码中。

我确实有一个解决方法,我会将页面批处理成单独的文件然后使用提到的here合并它们 - 然而,为了避免这种情况,它肯定会更加高效和清洁。 / p>

请参阅下面的代码摘要:

File sourceFile = new File (C:\\Temp\\extractFROM.pdf);
PDDocument sourceDocument = PDDocument.load(SourceFile, MemoryUsageSetting.setupTempFileOnly();
PDPageTree sourcePageTree = sourceDocument.getDocumentCatalog().getPages(); 
PDDocument tempDocument = new PDDocument (MemoryUsageSetting.setupTempFileOnly())

for (PDPage page : sourcePageTree) {
// Code to extract page text and confirm if contains String
if (above psuedo code is true) {
tempDocument.importPage(page);
}
}

tempDocument.save(sourceFile);

一旦它被导出大约7000页左右,那就是它在 tempDocument.importPage(页面)行中轰炸出来的时候。它适用于低于该数字的PDF。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

运行到OutofMemoryError的程序可能有内存泄漏,或者可能只需要更多内存才能正常运行。

因此,在这种情况下尝试的一个变化是简单地增加分配给程序的内存。如果程序运行没有问题,您可以认为这是一个修复。只要分配的内存不会变得完全不合理,那就是......

这似乎是这里的情况,因为操作确认

  

我已将堆作为运行配置增加到670mb(我可以用我的客户端设备保护最大值)这已经成功解决了问题 - 事实上,我在PDF上尝试了两倍于原来的失败PDF ,它也很容易管理。