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数据结构中堆的向下和向上调整解析

    Java数据结构中堆的向下和向上调整解析

    堆是一颗完全二叉树,在这棵树中,所有父节点都满足大于等于其子节点的堆叫大根堆,所有父节点都满足小于等于其子节点的堆叫小根堆。堆虽然是一颗树,但是通常存放在一个数组中,父节点和孩子节点的父子关系通过数组下标来确定
    2021-11-11
  • Java使用单链表实现约瑟夫环

    Java使用单链表实现约瑟夫环

    这篇文章主要为大家详细介绍了Java使用单链表实现约瑟夫环,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 关于SpringBoot的异常回滚和事务的使用详解

    关于SpringBoot的异常回滚和事务的使用详解

    这篇文章主要介绍了关于SpringBoot的异常回滚和事务的使用详解,Spring中 @Transactional 注解,默认情况下,只对抛出的RuntimeException 异常,才会事务回滚,需要的朋友可以参考下
    2023-05-05
  • 基于Maven pom文件使用分析

    基于Maven pom文件使用分析

    本文详细介绍了Maven项目的核心配置文件pom.xml的结构和各个元素的用途,包括项目基础信息、依赖管理、仓库配置、构建配置、版本控制、分发和报告配置等,帮助读者全面了解Maven项目的构建和管理过程
    2024-12-12
  • 解析Java继承中方法的覆盖和重载

    解析Java继承中方法的覆盖和重载

    这篇文章主要介绍了Java继承中方法的覆盖和重载的详细概念及用法,非常的实用,这里推荐给大家,有需要的小伙伴可以参考下。
    2015-05-05
  • Java实现计算器设计

    Java实现计算器设计

    这篇文章主要为大家详细介绍了Java实现计算器设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java8接口中引入default关键字的本质原因详析

    Java8接口中引入default关键字的本质原因详析

    Default方法是在java8中引入的关键字,也可称为Virtual extension methods—虚拟扩展方法,这篇文章主要给大家介绍了关于Java8接口中引入default关键字的本质原因,需要的朋友可以参考下
    2022-01-01
  • CentOS 7快速安装jdk

    CentOS 7快速安装jdk

    这篇文章主要为大家详细介绍了CentOS 7快速安装jdk的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Java实现分解任意输入数的质因数算法示例

    Java实现分解任意输入数的质因数算法示例

    这篇文章主要介绍了Java实现分解任意输入数的质因数算法,涉及java数学运算相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • java压缩多个文件并且返回流示例

    java压缩多个文件并且返回流示例

    这篇文章主要介绍了java压缩多个文件并且返回流示例,返回压缩流主是为了在程序里再做其它操作,需要的朋友可以参考下
    2014-03-03

最新评论