如何在Java中对数据库Blob存储的PDF文件进行压缩打包
解决Blob格式PDF打包成Zip的问题
我来帮你完善代码!你的现有代码已经搭好了Zip打包的基础框架,但还没把BlobDomain里的PDF内容写入到Zip中,而且流的管理方式也可以更安全可靠。下面是完整的解决方案:
问题分析
你的代码里连续调用了putNextEntry()但没有写入对应条目的内容就直接切换到下一个,这样生成的PDF文件会是空的。另外手动关闭流容易遗漏,推荐用try-with-resources语法自动管理资源,避免内存泄漏。
完整代码实现
import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; // 假设你的BlobDomain类提供了获取Blob内容输入流的方法 public class BlobToZipConverter { public static void main(String[] args) { // 模拟从数据库获取BlobDomain对象 BlobDomain doc1 = (BlobDomain) rowshis[0].getAttribute("Document"); BlobDomain doc2 = (BlobDomain) rowshis[1].getAttribute("Document"); StringBuilder sb = new StringBuilder(); sb.append("Test Date"); // 目标Zip文件路径 File targetZip = new File("/customer/scratch/HDLtest.zip"); // 使用try-with-resources自动关闭所有流资源,无需手动调用close() try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(targetZip)); InputStream pdfStream1 = doc1.getInputStream(); InputStream pdfStream2 = doc2.getInputStream()) { // 处理第一个PDF文件:BlobFiles/807.pdf ZipEntry pdfEntry1 = new ZipEntry("BlobFiles/807.pdf"); zipOut.putNextEntry(pdfEntry1); // 用缓冲区循环读取Blob内容,写入Zip byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = pdfStream1.read(buffer)) != -1) { zipOut.write(buffer, 0, bytesRead); } zipOut.closeEntry(); // 关闭当前条目,切换到下一个 // 处理第二个PDF文件:BlobFiles/1285.pdf ZipEntry pdfEntry2 = new ZipEntry("BlobFiles/1285.pdf"); zipOut.putNextEntry(pdfEntry2); while ((bytesRead = pdfStream2.read(buffer)) != -1) { zipOut.write(buffer, 0, bytesRead); } zipOut.closeEntry(); // 处理Test.dat文件 ZipEntry testEntry = new ZipEntry("Test.dat"); zipOut.putNextEntry(testEntry); byte[] testData = sb.toString().getBytes(); zipOut.write(testData, 0, testData.length); zipOut.closeEntry(); System.out.println("Zip文件生成成功!"); } catch (Exception e) { e.printStackTrace(); // 这里可以添加自定义异常处理,比如日志记录、错误提示等 } } }
关键细节说明
- 读取Blob内容:通过
BlobDomain.getInputStream()获取PDF的输入流,用4KB缓冲区循环读取写入Zip,能高效处理大文件,避免内存溢出。如果你的BlobDomain获取流的方法不是getInputStream(),可以根据实际API调整(比如部分框架用getBinaryStream()),核心逻辑一致。 - 流资源安全:try-with-resources会在代码块执行完毕后,自动关闭所有实现了
AutoCloseable接口的资源,彻底避免手动关闭流时可能出现的遗漏或异常。 - 条目处理规范:每个ZipEntry在调用
putNextEntry()后必须写入对应内容,再调用closeEntry(),否则会导致文件内容错乱或为空。
内容的提问来源于stack exchange,提问作者Vikram Srinivasan
相关产品推荐
相关产品推荐

