• 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;
        }
    
    }
    
  • 相关阅读:
    Git常用
    自学过程
    SpringJunitTest
    通过Maven更换环境配置文件
    MongDB的DateZone
    工具使用问题
    项目中遇到的关于Java的问题
    iTerm2使用Profiles自动登录
    脚本:将git项目下载到本地并启动
    一些新的认识
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/15819232.html
Copyright © 2020-2023  润新知