使用Apache PdfBox合并PDF时出现End-of-File Exception问题求助
PDF合并时End-of-File Exception的排查与修复
错误原因分析
从堆栈跟踪来看,异常发生在PDF头部解析阶段,说明某个输入流为空或不是有效的PDF数据,可能的触发点包括:
- 传入的
byteArray为空,或本身不是合法的PDF字节数据 - resources目录下的
/pdf/pdfTwo.pdf不存在,导致getResourceAsStream返回null,后续读取空流报错 - 临时文件写入未完成或失败,导致第一个PDF流无效
- 流未正确关闭或管理,引发读取异常
修复方案
1. 省略临时文件,直接用字节流处理
不需要将byteArray写入临时文件,直接用ByteArrayInputStream包装,减少文件IO环节的出错可能。
2. 校验输入流有效性
- 检查传入的
byteArray是否为空或长度为0 - 确认resources下的PDF文件存在,且
getResourceAsStream返回的流不为null,避免读取空流
3. 使用try-with-resources自动管理流
确保所有输入输出流自动关闭,避免资源泄漏和流读取异常。
修正后的代码
public byte[] mergedPdfs(byte[] byteArray) throws IOException { // 校验传入的字节数组有效性 if (byteArray == null || byteArray.length == 0) { throw new IllegalArgumentException("传入的PDF字节数组不能为空"); } // 直接用ByteArrayInputStream包装字节数组,无需临时文件 try (InputStream pdfOne = new ByteArrayInputStream(byteArray); // 获取resources下的PDF流,同时校验是否存在 InputStream pdfTwo = Thread.currentThread().getContextClassLoader().getResourceAsStream("/pdf/pdfTwo.pdf"); ByteArrayOutputStream mergedPdfs = new ByteArrayOutputStream()) { if (pdfTwo == null) { throw new FileNotFoundException("resources目录下未找到/pdf/pdfTwo.pdf文件"); } PDFMergerUtility pdfMergerUtility = new PDFMergerUtility(); pdfMergerUtility.setDestinationStream(mergedPdfs); pdfMergerUtility.addSource(pdfOne); pdfMergerUtility.addSource(pdfTwo); pdfMergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()); return mergedPdfs.toByteArray(); } }
额外检查点
- 验证传入的
byteArray是否为合法PDF:可以检查数组前几个字节是否为%PDF-开头(PDF文件的标准头部标识) - 确认resources目录下的
pdfTwo.pdf路径正确,打包后是否包含在jar/war中(比如Maven项目中,resources下的文件默认会被打包到classpath根目录)
内容的提问来源于stack exchange,提问作者TBa
相关产品推荐
相关产品推荐

