java - 使用 PdfBox 添加页面后尝试保存 PDF 时出现“IOException:COSStream 已关闭且无法读取”
问题描述
我很难让这段代码正常工作。目标是将 pdf 与 PDDocument 对象中加载的 pdf 合并。我不想使用 PdfBox 的 mergeUtility 因为它意味着关闭 PDDocument 对象。我有很多数据要处理,我使用循环来处理它。加载和关闭 PDDocument 将花费太多时间和资源(也许我错了,但感觉就是这样)。
这是我的方法:
for (String path:pathList) {
/* ... */
if(path.endsWith("pdf")){
File pdfToMerge = new File(path);
try(PDDocument pdfToMergeDocument = PDDocument.load(pdfToMerge)){
for (int pageIndex = 0; pageIndex < pdfToMergeDocument.getNumberOfPages(); pageIndex++){
PDPage page = pdfToMergeDocument.getPage(pageIndex);
doc.addPage(page);
}
}catch (IOException e){
System.out.println("Pdf : " + path + ANSI_RED + " [FAILED]" + ANSI_RESET);
continue;
}finally {
System.out.println("Pdf : " + path + ANSI_GREEN +" [OK]" + ANSI_RESET);
}
}
}
doc.save("src/Kairos/OutPut/"+pdfName[pdfName.length - 1]+".pdf");
doc.close();
当我尝试在第 65 行保存文档时发生错误。
我收到此错误消息:
Exception in thread "main" java.io.IOException: COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
at org.apache.pdfbox.cos.COSStream.checkClosed(COSStream.java:83)
at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:133)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1214)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:402)
at org.apache.pdfbox.cos.COSObject.accept(COSObject.java:158)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:521)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:459)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:443)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1108)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:449)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1381)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1268)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1334)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1305)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1293)
at Kairos.Main.main(Main.java:65)
解决方案
考虑一下:你有一个String
s列表,pathList
然后你遍历它。
在第一个循环结束时,您保存doc
并关闭它。
然后你再次循环并尝试保存doc
. 您在上一次迭代中关闭的。
如果您的目标是将所有 pdf 的内容放入pathList
指向的pdf 中doc
,则必须在循环完所有pathList
.
编辑:
正如 Tilman Hausherr 所指出的,还有另一个问题。当您打电话时,addPage
您并没有复制原始页面,而是或多或少地链接到它。由于您使用的是 try-with-resources 构造,因此原始文件在try-catch
构造结束时关闭,这意味着,一旦您退出构造,您就会失去对原始页面的任何引用。因此,您必须在退出之前try-catch
保存,否则您将使用importPage
它来制作副本(然后addPage
无论如何都会调用)。所以
PDPage page = pdfToMergeDocument.getPage(pageIndex);
doc.importPage(page);
编辑2:
当然,这个答案现在是错误的,因为 OP 在原始问题中发布了错误的代码 :) 我将把它留在这里以防万一有人需要它。
推荐阅读
- mysql - 使用 Laravel db builder 在查询中执行 WITH MySQL 表达式
- java - 我可以阻止 JLI_Launch 调用调用者的“int main (int argc, char *argv[])”吗?
- pandas - Pandas 使用索引将行值替换为零
- swift - 使用金属着色器移动图像
- r - 更改标题:带 ggplot 的 mcmc_trace 函数
- python - 不知道为什么pytorch.tensor的对应存储每次resize都会改变?
- node.js - 如何解决同时运行多个脚本的问题
- linux - 从 shell 脚本解析日期以计算证书到期前的天数
- julia - 使用 Jump 获取不可约不一致子系统 (IIS) - Julia
- javascript - 是否可以使用 JavaScript 将网站上的现有价格替换为转换后的价格?