2014-04-08 116 views
5

我试图将PDF文件的第一页转换为使用PDFBox的图像。 当我加载一个大的PDF文件时,我得到一个异常。PDFbox加载大文件

代码:

PDDocument doc; 
    try { 
     InputStream input = new URL("http://www.jewishfederations.org/local_includes/downloads/39497.pdf").openStream(); 
     doc = PDDocument.load(input); 
     PDPage firstPage = (PDPage) doc.getDocumentCatalog().getAllPages().get(0); 
     BufferedImage image =firstPage.convertToImage(); 
     File outputfile = new File("image2.png"); 
     ImageIO.write(image, "png", outputfile); 
     input.close(); 
     doc.close(); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

例外:

org.apache.pdfbox.pdfparser.BaseParser parseCOSStream 
WARNING: Specified stream length 72435 is wrong. Fall back to reading stream until 'endstream'. 
org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 72435 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize 
    at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:554) 
    at org.apache.pdfbox.pdfparser.PDFParser.parseObject(PDFParser.java:605) 
    at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:194) 
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1219) 
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1186) 
    at Worker.main(Worker.java:27) 
Caused by: java.io.IOException: Push back buffer is full 
    at java.io.PushbackInputStream.unread(Unknown Source) 
    at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:144) 
    at org.apache.pdfbox.io.PushBackInputStream.unread(PushBackInputStream.java:133) 
    at org.apache.pdfbox.pdfparser.BaseParser.parseCOSStream(BaseParser.java:550) 
    ... 5 more 
+0

当您增加推回缓冲区大小时会发生什么? – azurefrog

+0

到目前为止,我没有找到如何做到这一点。 – user2958571

+1

你自己的错误消息说:'尝试增加推回缓冲区使用系统属性org.apache.pdfbox.baseParser.pushBackSize' – azurefrog

回答

2

首先,找到当前的缓冲区大小:

System.out.println(System.getProperty("org.apache.pdfbox.baseParser.pushBackSize")); 

现在,你有一个底线,做的正是它暗示。将缓冲区大小增加到刚才打印出来的数值上面:

System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "<buffer size>"); 

保持增加缓冲区大小直到它工作。希望你不会耗尽内存,如果你增加堆。

这是您在运行时设置系统属性的方式。你也可以将它作为参数传递,但是我发现在main的开头附近设置会实现这个诀窍,并且使未来的开发人员更容易维护该项目。

无论出于何种原因,对于大文件,您没有足够大的缓冲区来加载页面。也许在页面被渲染成图像之前或之后,页面被加载到缓冲区中。我的猜测是PDF中的DPI非常高,不适合缓冲区。

+0

你的答案是完美的最后一段。在“旧”分析器中,当流的长度不正确时使用推回缓冲器,即PDF格式错误(“指定的流长度72435是错误的”消息)。在这种情况下,解析器必须“返回”,并且默认的pushbackbuffer长度为65536,因此“繁荣”。 –

+0

@guyfleeman在哪里可以找到pdfbox的属性列表? – XY6

2

1.8。* PDFBox版本的替代解决方案是使用非顺序分析器。在这种情况下,代码不会

doc = PDDocument.load(input); 

doc = PDDocument.loadNonSeq(input, null); 

该解析器(这将是在即将到来的2.0版本的仅一个)独立于推回缓冲区的大小。

1

我也有类似的问题,我认为是与基于误差较大的PDF文件,但事实证明并非如此。它原来是一个腐败的pdf文件。

供我们使用的情况下,我们有一个PDF模板文件(我们以编程方式填充其形式值)为我们的项目资源即熟到我们的战争。

我看到的例外是:org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 480478 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize。我们添加了这个属性,然后再运行一些东西,我们得到了另一个问题。

下一个堆栈跟踪声明“无法读取字体TimesNewRoman,Bold的嵌入式TTF”。我们花了一段时间,然而在爆炸战争并试图在战争中打开pdf文件后,我们注意到它是腐败的,但源文件中的pdf文件没有损坏,可以毫无问题地打开。

我们问题的根本原因是我们在我们的资源文件夹中添加了“过滤”。我们这样做,使我们可以利用一些反射来获取我们的健康检查网页的一些值,但损坏的PDF文件,我们从下面的参考想通了:https://bitbucket.org/petermr/xhtml2stm/issues/12/pdf-files-are-being-corrupted-at-some

下面是过滤,我们设置的例子这一点我们:

<resources> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>true</filtering> 
    </resource> 
</resources> 

我们的解决方案是从我们的POM删除此返工我们是如何走到了我们的健康页面中的信息。