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 等压缩包。
代码
- 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);
}
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
