“IOException: COSStream 已关闭且无法读取"在使用 PdfBox 添加页面后尝试保存 PDF 时 [英] "IOException: COSStream has been closed and cannot be read" when trying to save PDF after adding page with PdfBox

查看:55
本文介绍了“IOException: COSStream 已关闭且无法读取"在使用 PdfBox 添加页面后尝试保存 PDF 时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用此代码时遇到了一些麻烦.目标是将 pdf 与 PDDocument 对象中加载的 pdf 合并.我不想使用 PdfBox 的 mergeUtility 因为它意味着关闭 PDDocument 对象.我有很多数据要处理,我使用循环来处理它.加载和关闭 PDDocument 将花费太多时间和资源(也许我错了,但它的感觉).

I have some trouble to get this code working. The goal is to merge pdf with a loaded pdf in a PDDocument object. I don't want to use the mergeUtility of PdfBox because it implies to closed the PDDocument object. I have a lot of data to process and I use a loop to process it. Load and close a PDDocument will take too much time and resource (maybe I'm wrong but that the way it feel it).

这是我的方法:

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 行.

The error happen when I try to save the document, on line 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)

推荐答案

考虑这个:你在 pathList 中有一个 String 的列表,你可以遍历它.

Consider this: you have a list of Strings in pathList and you iterate through it.

在第一个循环结束时保存 doc 并关闭它.

At the end of the first loop you save doc and you close it.

然后您再次循环并尝试保存doc.您在上一次迭代中关闭的.

Then you loop again and try to save doc. Which you closed in the previous iteration.

如果您的目标是将 pathList 中所有 pdf 的内容放在 doc 指向的 pdf 中,则必须将其关闭 outside 循环,在您遍历所有 pathList 之后.

If your objective is to put the contents of all the pdfs in pathList inside the pdf pointed to by doc, you have to close it outside the loop, after you looped over all of pathList.

正如 Tilman Hausherr 所指出的,还有另一个问题.当您调用 addPage 时,您不是在复制原始页面,而是或多或少地链接到它.由于您使用的是 try-with-resources 构造,原始文件在 try-catch 构造结束时关闭,这意味着,一旦退出构造,您将丢失任何引用到原始页面.所以你必须在退出 try-catch 之前保存 或者你使用 importPage 代替,它会制作一个副本(然后将调用 addPage 反正).所以

As pointed out by Tilman Hausherr, there's another problem. When you call addPage you're not making a copy of the original page, you're more or less linking to it. Since you're using a try-with-resources construct, the original file gets closed at the end of the try-catch construct, meaning that, as soon as you exit the construct, you lose any reference to the original page. So you have to save before exiting the try-catch or you use importPage instead, which makes a copy (and will then call addPage anyway). So

PDPage page = pdfToMergeDocument.getPage(pageIndex);
doc.importPage(page);

编辑 2:

当然这个答案现在是错误的,因为 OP 在原始问题中发布了错误的代码 :) 如果有人需要它,我会把它留在这里.

Of course this answer is now wrong because OP posted the wrong code in the original question :) I'll leave this here in case anyone needs it.

这篇关于“IOException: COSStream 已关闭且无法读取"在使用 PdfBox 添加页面后尝试保存 PDF 时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆