SpringBoot解压缩ZIP,7Z,RAR5(兼容RAR4)

本文介绍了如何在Java生产环境中使用ApacheAnt和SevenZipJBinding库解压ZIP和7Z文件,以及如何处理RAR解压的复杂性,包括文件名编码问题。作者分享了解压代码片段及其应用场景。
摘要由CSDN通过智能技术生成

这三个解压缩是我在工作中遇到的需求,在经过一天的搜索整理之后终于完成了

本文中的方法是可以在生产环境之中使用,由于业务需求所以我的方法返回的是解压缩之后的文件名,大家按照自己的需求更改返回值即可

将文件编码进行赋值,以免文件解压缩之后文件名以及文件内容出现乱码,本人确实出现过这种情况,所以长教训了

private static final String CHINESE_CHARSET = "GBK";

解压ZIP

 代码中zipFilePath为压缩文件位置    destDir 为解压后的位置

导入依赖

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant</artifactId>
    <version>1.9.6</version>
</dependency>

代码 

private List<String> unzip(String zipFilePath, String destDir) {
        List<String> nameList = new ArrayList<>();
        ZipFile zipFile = null;
        try {
            BufferedInputStream bis = null;
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            zipFile = new ZipFile(zipFilePath, CHINESE_CHARSET);
            Enumeration<ZipEntry> zipEntries = zipFile.getEntries();
            File file, parentFile;
            ZipEntry entry;
            byte[] cache = new byte[1024];

            while (zipEntries.hasMoreElements()) {
                entry = (ZipEntry) zipEntries.nextElement();
                if (entry.isDirectory()) {
                    new File(destDir + entry.getName()).mkdirs();
                    continue;
                }
                bis = new BufferedInputStream(zipFile.getInputStream(entry));
                long time = System.currentTimeMillis();
                file = new File(destDir+time+"_"+ entry.getName());
                //获取文件名
                String fileName = file.getName()
                nameList.add(fileName);
                parentFile = file.getParentFile();
                if (parentFile != null && (!parentFile.exists())) {
                    parentFile.mkdirs();
                }
                fos = new FileOutputStream(file);
                bos = new BufferedOutputStream(fos, 1024);
                int readIndex = 0;
                while ((readIndex = bis.read(cache, 0, 1024)) != -1) {
                    fos.write(cache, 0, readIndex);
                }
                bos.flush();
                bos.close();
                fos.close();
                bis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }finally{
            try {
                zipFile.close();
            } catch (IOException e) {
                e.printStackTrace();
                return new ArrayList<>();
            }
        }
        return nameList;
    }

 解压7Z

导入依赖

<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding</artifactId>
    <version>16.02-2.01</version>
</dependency>

代码

private List<String> un7z(String zipFilePath, String destDir){
        List<String> nameList = new ArrayList<>();
        SevenZFile zIn = null;
        try {
            File file = new File(zipFilePath);
            zIn = new SevenZFile(file);
            SevenZArchiveEntry entry = null;
            File newFile = null;
            long time = System.currentTimeMillis();
            while ((entry = zIn.getNextEntry()) != null){
                //不是文件夹就进行解压
                if(!entry.isDirectory()){
                    newFile = new File(destDir,time+"_"+ entry.getName());
                    String fileName = newFile.getName();
                    nameList.add(fileName);
                    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) {
            e.printStackTrace();
            return new ArrayList<>();
        }finally {
            try {
                if (zIn != null){
                    zIn.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                return new ArrayList<>();
            }
        }

        return nameList;
    }

解压rar

个人觉得解压RAR是最难的,因为RAR5的解压并未开源,所以需要很多其他的操作,具体的代码如何操作请大家自己花费一些时间来理解

导入依赖

<dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>java-unrar</artifactId>
    <version>1.7.0-8</version>
</dependency>

首先解压rar需要创建一个工具类ExtractCallback

public class ExtractCallback implements IArchiveExtractCallback {

    private int index;
    private IInArchive inArchive;
    private String ourDir;
    private List<String> nameList = new ArrayList<>();

    public ExtractCallback(IInArchive inArchive, String ourDir) {
        this.inArchive = inArchive;
        this.ourDir = ourDir;
    }

    @Override
    public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode)throws SevenZipException {
        this.index = index;
        final String path = (String) inArchive.getProperty(index, PropID.PATH);
        final boolean isFolder = (boolean) inArchive.getProperty(index,PropID.IS_FOLDER);
        final String[] oldPath = {""};
        long time = System.currentTimeMillis();
        return new ISequentialOutStream() {
            @Override
            public int write(byte[] data) throws SevenZipException {
                try {
                    if (!isFolder) {
                        File file = new File(ourDir +time+"_"+ path);
                        final String fileName = file.getName();
                        int i = nameList.indexOf(fileName);
                        if (i==-1){
                            nameList.add(fileName);
                        }
                        if (path.equals(oldPath[0])) {
                            save2File(file, data, true);
                        } else {
                            save2File(file, data, false);
                        }
                        oldPath[0] = path;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    nameList = new ArrayList<>();
                }
                return data.length;
            }
        };
    }

    @Override
    public void prepareOperation(ExtractAskMode extractAskMode) throws SevenZipException {

    }

    @Override
    public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {

    }

    @Override
    public void setTotal(long l) throws SevenZipException {

    }

    @Override
    public void setCompleted(long l) throws SevenZipException {

    }

    public boolean save2File(File file, byte[] msg, boolean append) {
        FileOutputStream fos = null;
        try {
            File parent = file.getParentFile();
            boolean bool;
            if ((!parent.exists()) && (!parent.mkdirs())) {
                return false;
            }
            fos = new FileOutputStream(file, append);
            fos.write(msg);
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public List<String> getNameList() {
        return nameList;
    }

    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }
}

使用unrar方法调用工具类,进行解压,unrar方法传入参数rarFile为压缩文件, dstDirectoryPath为解压后的文件位置,其实压缩文件也好,压缩文件位置也好,本质都是相同的,都是找到这个压缩文件进行解压

实现代码

public static List<String> unRar(File rarFile,String dstDirectoryPath){
        IInArchive archive;
        RandomAccessFile randomAccessFile;
        try {
            randomAccessFile = new RandomAccessFile(rarFile,"r");
            archive = SevenZip.openInArchive(null,new RandomAccessFileInStream(randomAccessFile));
            int[] in = new int[archive.getNumberOfItems()];
            for (int i = 0; i < in.length; i++) {
                in[i] = i;
            }
            final ExtractCallback extractCallback = new ExtractCallback(archive, dstDirectoryPath);
            archive.extract(in,false,extractCallback);
            archive.close();
            randomAccessFile.close();
            return extractCallback.getNameList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

本次的文章就分享到这,分享这篇文章是因为想留作日后再遇到此类需求时不用再去苦苦寻找,希望这篇文章能够帮助各位,由于是本人第一次分享,文笔或代码可能说的不清晰或有瑕疵,请各位包容指正,感谢

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值