Java原生库解压Zip流报MALFORMED错
- 压缩包内部,若内部节点(文件或目录)名称包含非拉丁文,跨平台传递时,比如发送方用的utf-8,而接收方用的是gbk,若直接使用jdk原生的库解压流去解析,就会报错,如下:
java.lang.IllegalArgumentException: MALFORMED
at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:300)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:122)
- 解决方式是使用Apach-commons-compress能够获得更好的兼容性,只需引入如下依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
</dependency>
- 代码修改:
package com.yang.helper;
import lombok.SneakyThrows;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
/**
* 流zip工具类
*/
public final class StreamZipUtil {
/**
* 解压流
*
* @param inputStream
* @return
*/
@SneakyThrows
public static InputStream unzipStream(InputStream inputStream) {
//Fail-Fast
if (inputStream == null) {
return null;
}
//1.采用jdk原生Zip流,会因为发送方和接收方,在处理文件或文件夹名称时用的【字符集编码】不匹配,而报MALFORMED错(畸形的)
//ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//2.Apach-commons-compress的Zip流,兼容性更好
ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (zipInputStream.getNextEntry() != null) {
int n;
byte[] buff = new byte[1024];
while ((n = zipInputStream.read(buff)) != -1) {
bos.write(buff, 0, n);
}
}
bos.flush();
bos.close();
return new ByteArrayInputStream(bos.toByteArray());
}
/**
* 压缩流
*
* @param txtName
* @param inputStream
* @return
*/
@SneakyThrows
public static ByteArrayOutputStream zipStream(String txtName, ByteArrayInputStream inputStream) {
//Fail-Fast
if (inputStream == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
zipOut.putNextEntry(new ZipEntry(txtName));
int n;
byte[] buffer = new byte[1024];
while ((n = inputStream.read(buffer)) != -1) {
zipOut.write(buffer, 0, n);
}
zipOut.close();
inputStream.close();
outputStream.close();
return outputStream;
}
}
学习使我充实,分享给我快乐!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合终身会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步