You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:45:03