前言
rar版本在5以下时,使用junrar可解压;rar版本在5及以上时,junrar不支持。此文章主要记录解决此问题的方法。
参考:参考文章
一、代码
1.工具类
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import java.io.*;
public class RarUtils {
/**
* 根据原始rar路径,解压到指定文件夹下
* 支持解压rar 5.0及其以上的
* @param srcRarPath 原始rar路径+name
* @param dstDirectoryPath 解压到的文件夹
*/
public static boolean unRarFile(String srcRarPath, String dstDirectoryPath) throws Exception {
boolean isValid = true;
RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
// 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
try {
randomAccessFile = new RandomAccessFile(srcRarPath, "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, false, new ExtractCallback(inArchive, "366", dstDirectoryPath));
} catch (FileNotFoundException | SevenZipException e) {
e.printStackTrace();
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
System.err.println("Error closing archive: " + e);
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
System.err.println("Error closing file: " + e);
}
}
}
return isValid;
}
}
2.ExtractCallback回调方法
import net.sf.sevenzipjbinding.;
import java.io.;
public class ExtractCallback implements IArchiveExtractCallback {
private int index;
private String packageName;
private IInArchive inArchive;
private String ourDir;
public ExtractCallback(IInArchive inArchive, String packageName, String ourDir) {
this.inArchive = inArchive;
this.packageName = packageName;
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);
// 添加新的“文件夹”层级
String newPath = ourDir + "\\" + "\\" + path;
return new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
try {
if (!isFolder) {
File file = new File(newPath);
save2File(file, data, false);
}
} catch (Exception e) {
e.printStackTrace();
}
return data.length;
}
};
}
@Override
public void prepareOperation(ExtractAskMode arg0) throws SevenZipException {
}
@Override
public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {
String path = (String) inArchive.getProperty(index, PropID.PATH);
boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);
}
public boolean save2File(File file, byte[] msg,boolean append) {
OutputStream 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 (FileNotFoundException e) {
return false;
} catch (IOException e) {
File parent;
return false;
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
}
}
二、文件层数修改
如果需要改变解压之后的文件层数,可在以下代码处修改
// 添加新的“文件夹”层级(此处可以添加文件夹层数)
/**
* String newPath = ourDir + "\\" +"666"+ "\\" + path; //这样在解压之后会多一层名为”666“的文件夹
*/
String newPath = ourDir + "\\" + "\\" + path;