java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java解压rar文件的方法

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

作者:香蕉加奶茶

这篇文章主要介绍了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 等压缩包。

代码

        <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);
    }
}

总结

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

您可能感兴趣的文章:
阅读全文