[英]PDFbox loading large files
我正在嘗試使用 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
1.8.* PDFBox 版本的替代解決方案是使用非順序解析器。 在這種情況下,代碼不會是
doc = PDDocument.load(input);
但
doc = PDDocument.loadNonSeq(input, null);
該解析器(將是即將到來的 2.0 版本中唯一的解析器)與推回緩沖區的大小無關。
首先,找到當前緩沖區大小:
System.out.println(System.getProperty("org.apache.pdfbox.baseParser.pushBackSize"));
現在你有了一個基線,完全按照它的建議去做。 使用此將緩沖區大小增加到您剛剛打印出來的大小:
System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "<buffer size>");
繼續增加緩沖區大小,直到它起作用為止。 希望你不會耗盡內存,如果你確實增加了堆。
這就是您在運行時設置系統屬性的方式。 您也可以將其作為參數傳遞,但我發現在 main 開頭附近設置可以解決問題,並使未來的開發人員更容易維護項目。
無論出於何種原因,對於大文件,您沒有足夠大的緩沖區來加載頁面。 也許頁面在渲染成圖像之前或期間被加載到緩沖區中。 我的猜測是 PDF 中的 DPI 非常高,無法放入緩沖區。
我有一個類似的問題,我認為這與基於錯誤的大型 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
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 文件未損壞,可以毫無問題地打開。
我們問題的根本原因是我們在 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 中刪除它,並重新設計我們獲取健康頁面信息的方式。
在 2.0.* 版本中,像這樣打開 PDF:
PDDocument doc = PDDocument.load(file, MemoryUsageSetting.setupTempFileOnly());
這將設置緩沖內存使用以僅使用大小不受限制的臨時文件(無主內存)。
祝你好運
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.