我使用 iText7 和 Java 来读取不是很大 (10-30MB) 的 PDF,但它们包含大量对象,导致在创建和使用 时出现
。 (内部OutOfMemoryError
问题>Pdf文档xref
表和Map/Tree/Pdf[Dict/Array]
对象有数百万个。)
例如,单个 PDF 可能只有 33MB,但它包含一个包含 800 页、100 万行的表,而 PdfDocument
内部的簿记容量已高达 400MB。这是示例代码和堆转储:
public static void main(String[] args) throws Exception {
// PDF file is 33MB on disk (one big table over 800 pages)
File pdf = new File("big.pdf"); // Also tried InputStream
PdfReader reader = new PdfReader(pdf); // 35MB heap
PdfDocument document = new PdfDocument(reader); // 400MB+ heap
// do stuff ... assuming we didn't get an OOM above
}
我们向 JVM 添加了更多内存,但我们不知道其中一些 PDF 可能有多大/复杂,因此需要一种长期解决方案,最好是让我们能够分段或按事件读取内容的解决方案-类回调方式(如XML+STAX/SAX)。
有没有更有效的方法来流式传输 PDF 或将其分解为给定文件或 InputStream
的子 PdfDocuments
?我们想要定位并提取诸如表单、表格、工具提示等对象。
更新:我与 IText 团队取得了联系,IText7 不允许部分阅读 PDF。因此,在这种情况下,除了添加更多 RAM 或预解析 PDF mysql 并查找“太多数据”(大量工作)之外,我无能为力。我还检查了 PDFBox
,它也遇到了同样的问题。
最佳答案
您可以执行以下操作来读取大文件:
RandomAccessSourceFactory rasf = new RandomAccessSourceFactory();
RandomAccessSource ras = rasf.createBestSource(file);
RandomAccessFileOrArray rafoa = new RandomAccessFileOrArray(ras);
PdfReader pdfReader = new PdfReader(rafoa, null);
关于java - 如何避免通过 iText7 阅读复杂的 PDF 时内存不足?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57828508/