Java代码对rar文件的解压缩,目前网上对于rar5压缩文件解压缩代码很少,在工作中因为要对rar5进行解压,将自己晕倒的坑记录下来。
使用的jar 是unrar
<!-- 压缩文件jar -->
<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 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));
System.out.println("=======================");
}
执行
public static void main(String[] args) throws Exception {
File f=new File("d:/file/aa.rar");
String targerFile="d:/file/newfile/";
uncompressAllFile(f,targerFile);
}
该代码可以使用rar 4 和rar5 的版本,但是在解压过程中会将压缩包中的空文件夹过滤掉
优化版
使用回调函数 将过滤掉的空文件夹重新创建
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();
}
}
}
}
调用
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));
System.out.println("=======================");
}
以上是本人在操作中遇到的问题,如有不足请大家一起指出来