Java原生库解压Zip流报MALFORMED错

  1. 压缩包内部,若内部节点(文件或目录)名称包含非拉丁文,跨平台传递时,比如发送方用的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)
  1. 解决方式是使用Apach-commons-compress能够获得更好的兼容性,只需引入如下依赖:
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-compress</artifactId>
  <version>1.18</version>
</dependency>
  1. 代码修改:
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;
    }

}
posted @   JaxYoun  阅读(4993)  评论(2)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示