基于java-unrar支持rar5的rar文件解压

1,211 阅读1分钟

注意事项

  1. 这个方法会把源文件给删掉,记得备份;如果不想删除源文件,把deleteFile相关的注释掉
  2. 该代码可以使用rar 4 和rar5 的版本,但是在解压过程中会将压缩包中的空文件夹过滤掉

依赖

<dependency>
  <groupId>com.github.axet</groupId>
  <artifactId>java-unrar</artifactId>
  <version>1.7.0-8</version>
</dependency>
<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>

调用方法

public static void main(String[] args) throws Exception {
    String pathDocument = "E://00//nginx.rar";
    File file = new File(pathDocument);
    if (!file.exists()) {
        System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
        return ;
    }
    //获取目录下子文件
    decoFile(file);
}

递归解压方法

//解压文件夹及文件夹下所有内容,自己
    public static Boolean decoFile(File file) throws Exception{
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
//            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return true;
        }
        if (file.isFile() && file.getName().endsWith("rar")){
            //如果是rar文件。解压,删除源rar文件,递归生成的新文件夹
            String absolutePath = file.getAbsolutePath();
            System.out.println("absolutePath = " + absolutePath);
            int i = absolutePath.lastIndexOf(".");
            absolutePath = absolutePath.substring(0,i);
            uncompressAllFile(file,absolutePath);
            //下面这个会删除源rar文件
            boolean delete = file.delete();
            decoFile(new File(absolutePath));
        }else if (file.isDirectory()){
            //获取目录下子文件
            File[] files = file.listFiles();
            //遍历该目录下的文件对象
            for (File f : files) {
                decoFile(f);
            }
        }
        return true;
    }

解压方法

 public static void uncompressAllFile(File newFile, String targetFilePath) throws Exception {
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        // 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
        randomAccessFile = new RandomAccessFile(newFile.getPath(), "r");
        inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
        int[] in = new int[inArchive.getNumberOfItems()];
        for (int i = 0; i < in.length; i++) {
            in[i] = i;
        }
//      inArchive.extract(in, true, new ExtractZipFileCallback(inArchive, targetFilePath));
        inArchive.extract(in, false, new ExtractCallback(inArchive,targetFilePath));
        inArchive.close();
        randomAccessFile.close();
        System.out.println("=======================");
    }

需要的其他类


import net.sf.sevenzipjbinding.*;

import java.io.*;

public class ExtractCallback implements IArchiveExtractCallback {


    private int index;
    private IInArchive inArchive;
    private String ourDir;

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


    @Override
    public void setCompleted(long arg0) throws SevenZipException {
    }

    @Override
    public void setTotal(long arg0) throws SevenZipException {
    }

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

        File file1 = new File(ourDir + File.separator+ path);
        File parentFile;
        if (!file1.exists() && isFolder) {
            if (!(parentFile = file1.getParentFile()).exists()) {
                parentFile.mkdirs();
            }
            if (!file1.isFile()) {
                file1.mkdir();
            }
        }
        return data -> {
            try {
                if (!isFolder) {
                    File file = new File(ourDir + path);
                    save2File(file1, data);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return data.length;
        };
    }

    @Override
    public void prepareOperation(ExtractAskMode arg0) throws SevenZipException {
    }

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

    }

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

}