2014-04-08 118 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刪除此返工我們是如何走到了我們的健康頁面中的信息。