PDFbox加载大文件

时间:2014-04-08 19:07:21

标签: java pdfbox

我尝试使用PDFBox将pdf文件的第一页转换为图像。 当我加载一个大的pdf文件时,我得到一个例外。

代码:

    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

4 个答案:

答案 0 :(得分:2)

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

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

现在您已经有了基线,请完全按照它的建议行事。使用以下内容将缓冲区大小增加到刚刚打印出来的大小:

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

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

这是在运行时设置系统属性的方法。您也可以将其作为参数传递,但我发现在main的开头附近的设置将起到作用,并使未来的开发人员更容易维护项目。

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

答案 1 :(得分:2)

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

doc = PDDocument.load(input);

doc = PDDocument.loadNonSeq(input, null);

该解析器(将是即将推出的2.0版本中唯一的解析器)与回推缓冲区的大小无关。

答案 2 :(得分: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。我们添加了属性然后再次运行,我们遇到了另一个问题。

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

我们问题的根本原因是我们添加了&#34;过滤&#34;在我们的资源文件夹的pom中。我们这样做是为了让我们可以使用一些反射来在健康检查页面中获取一些值,但是这会破坏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中删除它,并返工我们如何获取健康页面的信息。

答案 3 :(得分:0)

在2.0。*版本中,像这样打开PDF:

PDDocument doc = PDDocument.load(file, MemoryUsageSetting.setupTempFileOnly());

这将设置缓冲内存使用率,以仅使用大小不受限制的临时文件(无主内存)。

祝你好运