如何解决Java使用PDFBox合并PDF时出现的Stream closed错误
问题原因
- 核心错误是
mergeDocuments()方法调用位置错误:你在遍历每个文件的循环内每次添加源文件后就执行合并,该方法执行完成后会自动关闭目标输出流,第二次循环执行时流已经关闭,因此抛出Stream closed异常。该方法仅需在所有源文件全部添加完成后调用1次即可。 - 代码存在隐性编译错误:
directoryPath.list()返回的是文件名String数组,不是File数组,直接赋值给File[] files会报类型不匹配错误,需要改用listFiles()方法。 - 冗余代码:循环中加载的
PDDocument对象没有实际使用,属于无效代码可以删除。 - 目标文件路径配置、合并工具实例化不需要放在循环内,重复执行无意义还会增加额外开销。
修复后可运行代码
public static String PDFMergingForForeignModule(String folder_name) { // Java中反斜杠需要转义,建议后续改用File.separator兼容多系统 String path = "E:\\Code"; File directoryPath = new File(path); // 改用listFiles获取File数组,同时过滤非PDF文件避免后续报错 File[] files = directoryPath.listFiles((dir, name) -> name.toLowerCase().endsWith(".pdf")); // 空文件判断避免空指针异常 if (files == null || files.length == 0) { return ""; } String mergedFileName = "Merged_"+folder_name+".pdf"; String mergedFilePath = path + "\\"+ mergedFileName; mergePDFFiles(files, mergedFilePath); return mergedFilePath; } public void mergePDFFiles(File[] files, String filepath) { PDFMergerUtility pdfmerger = new PDFMergerUtility(); // 目标文件路径仅需设置1次 pdfmerger.setDestinationFileName(filepath); try { // 先循环添加所有待合并的PDF源文件 for (File file : files) { pdfmerger.addSource(file); } // 全部添加完成后仅执行1次合并操作 pdfmerger.mergeDocuments(); } catch (IOException e) { logger.error("合并PDF文件失败,错误信息: " + e.getMessage()); } }
额外注意事项
- 如果使用的是PDFBox 2.x以上版本,建议调用带内存配置的重载方法
mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()),避免大文件合并时内存溢出。 - 建议添加文件存在性、权限校验逻辑,避免传入无效文件导致合并失败。
内容的提问来源于stack exchange,提问作者Alex Pandian Bala Murugan
相关产品推荐
相关产品推荐

