Java解压rar文件的两种实现方法

 更新时间:2024年06月17日 09:00:23   作者:香蕉加奶茶  
这篇文章主要介绍了Java解压rar文件的两种实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java解压rar文件的两种方法

方法一

 private static void extractRar(String rarPath, String destDir) throws IOException, RarException {
        File dstDiretory = new File(destDir);
        if (!dstDiretory.exists()) {
            dstDiretory.mkdirs();
        }

        File rarFile = new File(rarPath);
        Archive archive = new Archive(new FileInputStream(rarFile));
        List<FileHeader> fileHeaders = archive.getFileHeaders();
        for (FileHeader fileHeader : fileHeaders) {
            if (fileHeader.isDirectory()) {
                String fileName = fileHeader.getFileNameW();
                if (!existZH(fileName)) {
                    fileName = fileHeader.getFileNameString();
                }
                File dir = new File(destDir + File.separator + fileName);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
            } else {
                String fileName = fileHeader.getFileNameW().trim();
                if (!existZH(fileName)) {
                    fileName = fileHeader.getFileNameString().trim();
                }
                File file = new File(destDir + File.separator + fileName);
                try {
                    if (!file.exists()) {
                        if (!file.getParentFile().exists()) {
                            file.getParentFile().mkdirs();
                        }
                        file.createNewFile();
                    }
                    FileOutputStream os = new FileOutputStream(file);
                    archive.extractFile(fileHeader, os);
                    os.close();
                } catch (Exception ex) {
                    throw ex;
                }
            }
        }
        archive.close();

    }

    //判断文件名有没有正则表达式
    public static boolean existZH(String str) {
        String regEx = "[\\u4e00-\\u9fa5]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        while (m.find()) {
            return true;
        }
        return false;
    }
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>

方法二

 /**
     * 采用命令行方式解压文件
     *
     * @param rarPath 压缩文件路径
     * @param destDir 解压结果路径
     * @param cmdPath WinRAR.exe的路径,也可以在代码中写死
     * @return
     */
    public static boolean realExtract(String rarPath, String destDir, String cmdPath) {
        File rarFile = new File(rarPath);
        // 解决路径中存在/..格式的路径问题
        destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();
        while (destDir.contains("..")) {
            String[] sepList = destDir.split("\\\\");
            destDir = "";
            for (int i = 0; i < sepList.length; i++) {
                if (!"..".equals(sepList[i]) && i < sepList.length - 1 && "..".equals(sepList[i + 1])) {
                    i++;
                } else {
                    destDir += sepList[i] + File.separator;
                }
            }
        }
        boolean bool = false;
        if (!rarFile.exists()) {
            return false;
        }
        // 开始调用命令行解压,参数-o+是表示覆盖的意思
        String cmd = cmdPath + " X -o+ " + rarFile + " " + destDir;
        System.out.println(cmd);
        try {
            Process proc = Runtime.getRuntime().exec(cmd);
            if (proc.waitFor() != 0) {
                if (proc.exitValue() == 0) {
                    bool = false;
                }
            } else {
                bool = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        rarFile.delete();
        return bool;
    }

Java解压 rar、zip、7z 等压缩包通用工具类

问题

项目中有一个需求,客户端上传压缩包到服务器,需要先解压压缩包,拿到文件后进一步业务处理(保存图片,导入excel表格中的数据等等)。

上传的压缩包有多种格式,可能是 rar 或者 zip,Java 自带的工具类只能解压 zip,rar 需要额外导入其他依赖来解压。

记录下当时项目中用来解压 rar 的代码,该工具类也可以解压 zip 7z 等压缩包。

代码

  • pom
        <dependency>
            <groupId>net.sf.sevenzipjbinding</groupId>
            <artifactId>sevenzipjbinding-all-platforms</artifactId>
            <version>16.02-2.01</version>
        </dependency>
        <dependency>
            <groupId>net.sf.sevenzipjbinding</groupId>
            <artifactId>sevenzipjbinding</artifactId>
            <version>16.02-2.01</version>
        </dependency>
  • 解压工具类
public class UnCompressUtil {
    private static final Logger logger = Logger.getLogger(UnCompressUtil.class.getCanonicalName());

    /**
     * 解压rar
     *
     * @param file rar
     * @param extractPath 解压路径
     */
    public static void unCompress(File file, String extractPath) {
        try{
            RandomAccessFile randomAccessFile = new RandomAccessFile(file.getAbsolutePath(), "r");
            IInArchive archive = SevenZip.openInArchive(null,  new RandomAccessFileInStream(randomAccessFile));
            // 解压⽂件路径
            File extractDir = new File(extractPath);
            if (!extractDir.isDirectory()) {
                extractDir.mkdir();
            }
            int[] in = new int[archive.getNumberOfItems()];
            for(int i=0;i<in.length;i++){
                in[i] = i;
            }
            archive.extract(in, false, new ExtractCallback(archive, extractDir.getAbsolutePath()));
            archive.close();
            randomAccessFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class ExtractCallback implements IArchiveExtractCallback {
        private final IInArchive inArchive;

        private final String extractPath;

        public ExtractCallback(IInArchive inArchive, String extractPath) {
            this.inArchive = inArchive;
            if (!extractPath.endsWith("/") && !extractPath.endsWith("\\")) {
                extractPath += File.separator;
            }
            this.extractPath = extractPath;
        }

        @Override
        public void setTotal(long total) {

        }

        @Override
        public void setCompleted(long complete) {

        }

        @Override
        public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
            return data -> {
                String filePath = inArchive.getStringProperty(index, PropID.PATH);
                FileOutputStream fos = null;
                try {
                    File path = new File(extractPath + filePath);

                    if(!path.getParentFile().exists()){
                        path.getParentFile().mkdirs();
                    }

                    if(!path.exists()){
                        path.createNewFile();
                    }
                    fos = new FileOutputStream(path, true);
                    fos.write(data);
                } catch (IOException e) {
                    logger.log(null, "IOException while extracting " + filePath);
                } finally{
                    try {
                        if(fos != null){
                            fos.flush();
                            fos.close();
                        }
                    } catch (IOException e) {
                        logger.log(null, "Could not close FileOutputStream", e);
                    }
                }
                return data.length;
            };
        }

        @Override
        public void prepareOperation(ExtractAskMode extractAskMode) {

        }

        @Override
        public void setOperationResult(ExtractOperationResult extractOperationResult) {
        }

    }
}
  • 测试类
class UnCompressUtilTest {

    @Test
    void unCompress() {
        String rarPath = "C:\\Users\\XXX\\Desktop\\test.rar";
        File file = new File(rarPath);
        String extractPath = "C:\\Users\\XXX\\Desktop";
        UnCompressUtil.unCompress(file, extractPath);
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java多文件以ZIP压缩包导出的实现方法

    Java多文件以ZIP压缩包导出的实现方法

    这篇文章主要为大家详细介绍了Java多文件以ZIP压缩包导出的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Java使用OpenOffice将office文件转换为PDF的示例方法

    Java使用OpenOffice将office文件转换为PDF的示例方法

    OpenOffice是一个开源的办公套件,它包含了文档处理、电子表格、演示文稿以及绘图等多种功能,类似于Microsoft Office,本文将给大家介绍Java使用OpenOffice将office文件转换为PDF的示例方法,需要的朋友可以参考下
    2024-09-09
  • 手把手带你粗略了解Java--类和对象

    手把手带你粗略了解Java--类和对象

    这篇文章主要给大家介绍了关于java中类和对象的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Java Comparator.comparing比较导致空指针异常的解决

    Java Comparator.comparing比较导致空指针异常的解决

    这篇文章主要介绍了Java Comparator.comparing比较导致空指针异常的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Spring Boot 3.4.0 结合 Mybatis-plus 实现动态数据源的完整方案

    Spring Boot 3.4.0 结合 Mybatis-plus 实

    本文详细介绍了在 Spring Boot 3.4.0 项目中结合 Mybatis-plus 实现动态数据源切换的完整方案,通过自定义注解和AOP切面,我们可以优雅地实现方法级别的数据源切换,满足多数据源场景下的各种需求,感兴趣的朋友一起看看吧
    2025-04-04
  • 数据结构与算法之手撕排序算法

    数据结构与算法之手撕排序算法

    排序算法看似简单,其实不同的算法中蕴涵着经典的算法策略。通过熟练掌握排序算法,就可以掌握基本的算法设计思想,本文主要介绍了Java中的排序算法,需要的朋友欢迎阅读
    2023-04-04
  • 十五道tomcat面试题,为数不多的机会!

    十五道tomcat面试题,为数不多的机会!

    这篇文章主要介绍了十五道tomcat面试题,Tomcat的本质是一个Servlet容器。一个Servlet能做的事情是:处理请求资源,并为客户端填充response对象,需要的朋友可以参考下
    2021-08-08
  • 基于Java实现简易的局域网对话系统

    基于Java实现简易的局域网对话系统

    这篇文章主要介绍了基于Java实现的简易的局域网对话系统,文中的示例代码对我们学习Java有一定的帮助,感兴趣的小伙伴快来跟随小编一起学习一下吧
    2021-12-12
  • 最新log4j2远程代码执行漏洞(附解决方法)

    最新log4j2远程代码执行漏洞(附解决方法)

    Apache Log4j2 远程代码执行漏洞攻击代码,该漏洞利用无需特殊配置,经多方验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响,本文就介绍一下解决方法
    2021-12-12
  • Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析

    Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析

    这篇文章主要介绍了Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01

最新评论