“IOException: COSStream has been closed and cannot be read” when trying to save PDF after adding page with PdfBox

让人想犯罪 __ 提交于 2021-01-27 20:28:39

问题


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

Here is my way to do 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();

The error happen when I try to save the document, on line 65.

I get this error message :

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)

回答1:


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

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

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

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.

EDIT:

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);

EDIT 2:

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.



来源:https://stackoverflow.com/questions/57267528/ioexception-cosstream-has-been-closed-and-cannot-be-read-when-trying-to-save

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!