Java解压缩zip文件工具类(支持zip文件夹下多级目录结构)

版权声明:士,不可以不弘毅,任重而道远 https://blog.csdn.net/superbeyone/article/details/83339089


Java解压缩zip文件工具类(支持zip文件夹下多级目录结构)

1. 前言

由于工作需要一个能够解压缩zip的工具类,但查看了不少博客,发现查看的文章里都只支持zip文件夹下的一级文件结构,但实际生活中,zip文件夹下存在多级目录及文件是很随意的事情,所以萌生了封装这样一个能够解压缩多级目录结构文件的想法。

2. 正文

2.1 解压缩后文件目录结构展示

在这里插入图片描述

2.2 注意事项

  • 若zip文件中包含中文的话,可能需要制定字符编码,若不指定的话,默认使用UTF8字符编码
  • Windows系统压缩编码一般为GBKGB2312UTF8Linux系统压缩编码一般为UTF8
  • 测试数据使用GB2312能够正常解码,使用其它均不能正常解码

2.3 异常

2.3.1 可能会遇到的异常
java.lang.IllegalArgumentException: MALFORMED
	at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
	at java.util.zip.ZipFile.getZipEntry(ZipFile.java:583)
	at java.util.zip.ZipFile.access$900(ZipFile.java:60)
	at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:539)
	at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:514)
	at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:495)
	at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:91)
	at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:54)
	at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:34)
	at com.tdt.sc.utils.FileUtils.main(FileUtils.java:23)
2.3.2 解决方案
  • 此异常为字符编码解码异常
  • 建议使用其它字符编码进行解码,具体参见 注意事项

2.4 具体代码实现

import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @program: 
 * @description: 文件解压缩工具类
 * @author: Mr.superbeyone
 * @create: 2018-10-23 14:04
 **/
public class FileUtils {

    /**
     *  此方法将默认设置解压缩后文件的保存路径为zip文件所在路径
     *      即解压缩到当前文件夹下
     * @param zip zip文件位置
     * @param charsetName 字符编码
     */
    public static void unpack(String zip, String charsetName) {
        unpack(new File(zip), charsetName);
    }

    /**
     *
     * @param zip zip文件位置
     * @param outputDir 解压缩后文件保存路径
     * @param charsetName 字符编码
     */
    public static void unpack(String zip, String outputDir, String charsetName) {
        unpack(new File(zip), new File(outputDir), charsetName);
    }

    /**
     *  此方法将默认设置解压缩后文件的保存路径为zip文件所在路径
     *      即解压缩到当前文件夹
     * @param zip zip文件位置
     * @param charsetName 字符编码
     */
    public static void unpack(File zip, String charsetName) {
        unpack(zip, null, charsetName);
    }

    /**
     *
     * @param zip zip文件位置
     * @param outputDir 解压缩后文件保存路径
     */
    public static void unpack(File zip, File outputDir) {
        unpack(zip, outputDir, "");
    }

    /**
     *
     * @param zip zip文件位置
     * @param outputDir 解压缩后文件保存路径
     * @param charsetName 字符编码
     */
    public static void unpack(File zip, File outputDir, String charsetName) {

        FileOutputStream out = null;
        InputStream in = null;
        //读出文件数据
        ZipFile zipFileData = null;
        ZipFile zipFile = null;
        try {
            //若目标保存文件位置不存在
            if (outputDir != null) if (!outputDir.exists()) {
                outputDir.mkdirs();
            }
            if (charsetName != null && charsetName != "") {
                zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            } else {
                zipFile = new ZipFile(zip.getPath(), Charset.forName("utf8"));
            }
            //zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            //处理创建文件夹
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                String filePath = "";

                if (outputDir == null) {
                    filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
                } else {
                    filePath = outputDir.getPath() + File.separator + entry.getName();
                }
                File file = new File(filePath);
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
                if (parentFile.isDirectory()) {
                    continue;
                }
            }
            if (charsetName != null && charsetName != "") {
                zipFileData = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            } else {
                zipFileData = new ZipFile(zip.getPath(), Charset.forName("utf8"));
            }
            Enumeration<? extends ZipEntry> entriesData = zipFileData.entries();
            while (entriesData.hasMoreElements()) {
                ZipEntry entry = entriesData.nextElement();
                in = zipFile.getInputStream(entry);
                String filePath = "";
                if (outputDir == null) {
                    filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
                } else {
                    filePath = outputDir.getPath() + File.separator + entry.getName();
                }
                File file = new File(filePath);
                if (file.isDirectory()) {
                    continue;
                }
                out = new FileOutputStream(filePath);
                int len = -1;
                byte[] bytes = new byte[1024];
                while ((len = in.read(bytes)) != -1) {
                    out.write(bytes, 0, len);
                }
                out.flush();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
                zipFile.close();
                zipFileData.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.4 遗留问题

以下问题未做处理:

  1. 压缩文件内可能包含其它压缩文件
  2. 压缩文件内若存在空文件夹,则该文件夹会被当成文件处理,即生成以该文件夹名命名的空文件

猜你喜欢

转载自blog.csdn.net/superbeyone/article/details/83339089