使用zip4j生成加密Zip时,try块返回字节数组致格式错误的原因
Zip4j生成密码保护Zip文件格式错误的原因
你用Zip4j创建带密码的Zip文件时,原代码在try块内返回字节数组会导致文件格式错误,移到finally块之后就正常了,核心原因是ZipOutputStream的关闭操作才会完成Zip文件的最终写入。
原问题代码(错误版本)
fun createZipFile(filename: String, vararg containers: Pair<String, ByteArray?>): ByteArray { val out = ByteArrayOutputStream() val zipFile = ZipOutputStream(out, passwordGenerator.generate()); try { for ((name, file) in containers.toList()) { if (file != null) { val parameters = createZipParameters(name) zipFile.putNextEntry(parameters) zipFile.write(file) zipFile.closeEntry() } } // 这里返回会导致Zip文件不完整 return out.toByteArray() } finally { zipFile.close() out.close() } }
修改后代码(正常版本)
fun createZipFile(filename: String, vararg containers: Pair<String, ByteArray?>): ByteArray { val out = ByteArrayOutputStream() val zipFile = ZipOutputStream(out, passwordGenerator.generate()); try { for ((name, file) in containers.toList()) { if (file != null) { val parameters = createZipParameters(name) zipFile.putNextEntry(parameters) zipFile.write(file) zipFile.closeEntry() } } } finally { zipFile.close() out.close() } return out.toByteArray() }
具体原因解释
- Zip文件的结构不只是文件内容的简单拼接,它还包含中央目录记录和结束标记这些关键元数据,这些数据是解压工具识别Zip文件结构的核心依据。
- 在try块内返回时,你只写入了各个文件的内容,但
ZipOutputStream还没来得及把这些元数据写入到ByteArrayOutputStream里。此时拿到的字节数组只有零散的文件内容,缺少Zip格式必需的收尾数据,解压工具自然会报错“inappropriate format”。 - 当调用
zipFile.close()时,Zip4j的ZipOutputStream会自动完成最后一步:把所有未写入的元数据(比如文件索引、校验信息)写入到输出流,此时out里才是完整的Zip文件数据。把return放到finally之后,就能确保拿到的是完整的字节数组,自然可以正常打开。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

