文件压缩工具类,涵盖zip、rar、7z

一、添加依赖

<dependency>
    <groupId>org.tukaani</groupId>
    <artifactId>xz</artifactId>
    <version>1.8</version>
</dependency>
<!-- rar解压依赖 -->
<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding</artifactId>
    <version>16.02-2.01</version>
</dependency>
<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding-all-platforms</artifactId>
    <version>16.02-2.01</version>
</dependency>

二、压缩工具类

import lombok.extern.slf4j.Slf4j;
import net.sf.sevenzipjbinding.*;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

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


/**
 * 文件解压工具类
 */
@Slf4j
public class FileUnPacketUtil {
    /**
     * rar解压缩
     * @param file    压缩文件
     * @param outPath  解压路径
     * @return  压缩包中所有的文件
     */
    public static Map<String, String> unRarZip7Z(File file, String outPath) throws Exception {
        if (file.getName().toLowerCase().endsWith(".zip")) {
           return unZip(file, outPath, false);
        } else if (file.getName().toLowerCase().endsWith(".rar")) {
            return unRar(file, outPath, "");
        } else if (file.getName().toLowerCase().endsWith(".7z")) {
            return un7z(file, outPath);
        }
        return null;
    }

    /**
     * rar解压缩
     * @param rarFile    rar文件
     * @param outPath  解压路径
     * @return  压缩包中所有的文件
     */
    private static Map<String, String> unRar(File rarFile, String outPath, String passWord) {
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
            randomAccessFile = new RandomAccessFile(rarFile, "r");
            if (StringUtils.isNotBlank(passWord)) {
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile), passWord);
            } else {
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
            }

            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
            for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[]{0};
                if (!item.isFolder()) {
                    ExtractOperationResult result;
                    final long[] sizeArray = new long[1];

                    File outFile = new File(outPath + File.separator+ item.getPath());
                    File parent = outFile.getParentFile();
                    if ((!parent.exists()) && (!parent.mkdirs())) {
                        continue;
                    }
                    if (StringUtils.isNotBlank(passWord)) {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                 log.error("文件解压异常:{}",e);
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        }, passWord);
                    } else {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                 log.error("文件解压异常:{}",e);
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        });
                    }

                    if (result == ExtractOperationResult.OK) {
                        log.error("解压rar成功...." + String.format("%9X | %10s | %s", hash[0], sizeArray[0], item.getPath()));
                    } else if (StringUtils.isNotBlank(passWord)) {
                        log.error("解压rar成功:密码错误或者其他错误...." + result);
                    }
                }
            }

        } catch (Exception e) {
            log.error("unRar error", e);
        } finally {
            try {
                if(inArchive!=null){
                    inArchive.close();
                }
                if(randomAccessFile!=null){
                    randomAccessFile.close();
                }
            } catch (Exception e) {
                 log.error("文件解压异常:{}",e);
            }
        }
        Map<String, String> resultMap = getFileNameList(outPath);
        return resultMap;
    }


    /**
     * 获取压缩包中的全部文件
     * @param path    文件夹路径
     * @childName   每一个文件的每一层的路径==D==区分层数
     * @return  压缩包中所有的文件
     */
    private static Map<String, String> getFileNameList(String path) {
        log.info("path:" + path);
        Map<String, String> files = new HashMap<>();
        // 需要获取的文件的路径
        File file = new File(path);
        // 存储文件名的String数组
        String[] fileNameLists = file.list();
        // 存储文件路径的String数组
        File[] filePathLists = file.listFiles();
        for (int i = 0; i < filePathLists.length; i++) {
            if (filePathLists[i].isFile()) {
                files.put(fileNameLists[i] , path + File.separator + filePathLists[i].getName());
            } else {
                files.putAll(getFileNameList(path + File.separator + filePathLists[i].getName()));
            }
        }
        return files;
    }

    /**
     * zip解压缩
     * @param zipFile            zip文件
     * @param unzipFilePath            解压后文件保存路径
     * @param includeZipFileName    解压后文件是否包含压缩包文件名,true包含,false不包含
     * @return 压缩包中所有的文件
     */
    public static Map<String, String> unZip(File zipFile, String unzipFilePath, boolean includeZipFileName) throws Exception{
        //如果包含压缩包文件名,则处理保存路径
        if(includeZipFileName){
            String fileName = zipFile.getName();
            if(StringUtils.isNotEmpty(fileName)){
                fileName = fileName.substring(0,fileName.lastIndexOf("."));
            }
            unzipFilePath = unzipFilePath + File.separator + fileName;
        }

        //判断保存路径是否存在,不存在则创建
        File unzipFileDir = new File(unzipFilePath);
        if(!unzipFileDir.exists() || !unzipFileDir.isDirectory()){
            unzipFileDir.mkdirs();
        }

        //开始解压
        ZipEntry entry = null;
        String entryFilePath = null, entryDirPath = "";
        File entryFile = null, entryDir = null;
        int index = 0, count = 0, bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        Charset gbk = Charset.forName("GBK");
        ZipFile zip = new ZipFile(zipFile, gbk);
        try {
            Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
            while (entries.hasMoreElements()) {
                entry = entries.nextElement();
                entryFilePath = unzipFilePath + File.separator + entry.getName();
                entryFilePath = entryFilePath.replace("/", File.separator);
                index = entryFilePath.lastIndexOf(File.separator);
                if (index != -1) {
                    entryDirPath = entryFilePath.substring(0, index);
                }
                entryDir = new File(entryDirPath);
                if (!entryDir.exists() || !entryDir.isDirectory()) {
                    entryDir.mkdirs();
                }
                entryFile = new File(entryFilePath);
                //判断当前文件父类路径是否存在,不存在则创建
                if(!entryFile.getParentFile().exists() || !entryFile.getParentFile().isDirectory()){
                    entryFile.getParentFile().mkdirs();
                }
                //不是文件说明是文件夹创建即可,无需写入
                if(entryFile.isDirectory()){
                    continue;
                }
                bos = new BufferedOutputStream(new FileOutputStream(entryFile));
                bis = new BufferedInputStream(zip.getInputStream(entry));
                while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
                    bos.write(buffer, 0, count);
                }
                bos.flush();
                bos.close();
                bis.close();
            }
        }catch (Exception e){
             log.error("文件解压异常:{}",e);
        }finally {
            if(bos!=null){
                bos.close();
            }
            if(bis!=null){
                bis.close();
            }
            if(zip!=null){
                zip.close();
            }
        }
        Map<String, String> resultMap = getFileNameList(unzipFilePath);
        return resultMap;
    }
    /**
     * 7z解压缩
     * @param file    7z文件的全路径
     * @param outPath  解压路径
     * @return  压缩包中所有的文件
     */
    public static Map<String, String> un7z(File file, String outPath){

        SevenZFile zIn = null;
        try {
            zIn = new SevenZFile(file);
            SevenZArchiveEntry entry = null;
            File newFile = null;
            while ((entry = zIn.getNextEntry()) != null){
                //不是文件夹就进行解压
                if(!entry.isDirectory()){
                    newFile = new File(outPath, entry.getName());
                    if(!newFile.exists()){
                        //创建此文件的上层目录
                        new File(newFile.getParent()).mkdirs();
                    }
                    OutputStream out = new FileOutputStream(newFile);
                    BufferedOutputStream bos = new BufferedOutputStream(out);
                    int len = -1;
                    byte[] buf = new byte[(int)entry.getSize()];
                    while ((len = zIn.read(buf)) != -1){
                        bos.write(buf, 0, len);
                    }
                    bos.flush();
                    bos.close();
                    out.close();
                }
            }
        } catch (Exception e) {
             log.error("文件解压异常:{}",e);
        }finally {
            try {
                if (zIn != null) {
                    zIn.close();
                }
            } catch (IOException e) {
                 log.error("文件解压异常:{}",e);
            }
        }

        Map<String, String> resultMap = getFileNameList(outPath);
        return resultMap;
    }

}
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值