使用ZipOutputStream.putNextEntry()抛出ZipException:invalid entry size如何解决
错误根源
- 操作顺序错误:
ZipOutputStream.putNextEntry()需要在写入该条目内容之前调用,你先读完了当前条目的所有数据、只写入了单文件输出流,才调用putNextEntry(),此时ZipOutputStream没有拿到该条目的任何内容,所以会抛出条目大小不匹配的异常。 - 缺少数值写入逻辑:你遍历读取到的条目内容只写入了单文件的
FileOutputStream,完全没有写入ZipOutputStream,导致每个条目写入ZipOutputStream的大小都是0,和实际条目大小不符。 - 如果你本身的需求只是把内存中的zip字节数组存为本地zip文件,不需要做任何解压再重新打包的操作,现有逻辑完全冗余。
解决方案
方案1:仅需要将byte数组存为本地zip文件(最简实现)
不需要做任何流的解压封装,直接把byte数组写入目标文件即可:
FileOutputStream fos = new FileOutputStream(file); fos.write(plainText); fos.close();
方案2:需要同时解压zip内的所有文件到本地 + 生成原zip的本地副本
调整entry的读写顺序,读取条目内容后同时写入两个输出流即可:
InputStream plainTextStream = new ByteArrayInputStream(plainText); ZipInputStream zipInStream = new ZipInputStream(plainTextStream); ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(file)); ZipEntry entry = null; while((entry = zipInStream.getNextEntry()) != null){ // 先给输出zip添加当前条目 zipOutStream.putNextEntry(entry); // 创建单文件输出流 FileOutputStream fileOutStream = new FileOutputStream(entry.getName()); byte[] byteBuff = new byte[1024]; int bytesRead = 0; while ((bytesRead = zipInStream.read(byteBuff)) != -1) { // 同时把内容写到单文件和zip输出流 fileOutStream.write(byteBuff, 0, bytesRead); zipOutStream.write(byteBuff, 0, bytesRead); } fileOutStream.close(); zipOutStream.closeEntry(); zipInStream.closeEntry(); } // 最后关闭所有zip流 zipOutStream.close(); zipInStream.close();
内容的提问来源于stack exchange,提问作者AlMahiyan
相关产品推荐
相关产品推荐

