java压缩⽂件解压:调⽤WinRAR5命令强于⾃⼰写代码实现最近,⼿上维护着⼀个⼏年前的系统,技术是⽤的JSP+Strust2,系统提供了rar和zip两种压缩格式的解压功能,后台是⽤java实现的
1、解压rar格式,采⽤的是java-unrar-0.3.jar
2、解压zip格式,采⽤的是commons-compress-1.4.1.jar
但最近根据⽤户反馈的问题,发现系统存在两个关于压缩⽂件解压的问题:
1、有些压缩⽂件解压之后出现中⽂乱码;
2、有些压缩⽂件根本不能解压
为了弥补上述两个问题,在之前代码的基础上打了⼀些补丁,来解决zip压缩包乱码的问题,思路⼤概是:
1、采⽤GBK编码解压
2、递归遍历解压的⽂件名是否存在中⽂乱码,这⽤到了⽹上很常⽤的中⽂检测正则表⽰式,[\u4e00-\u9fa5]+
3、如果存在中⽂乱码,则采⽤UTF-8编码解压
替换后,还是有⼈反映乱码问题,烦~~~
第⼆个问题报错如下(出现在有些rar格式解压时):
WARNING: exception in archive constructor maybe file is encrypted or currupt
de.ption.RarException: badRarArchive
at de.innosystec.adHeaders(Archive.java:238)
at de.innosystec.unrar.Archive.setFile(Archive.java:122)
at de.innosystec.unrar.Archive.<init>(Archive.java:106)
at de.innosystec.unrar.Archive.<init>(Archive.java:96)
verse.zipFile.CopyOfZipFileUtil.unrar(CopyOfZipFileUtil.java:242)
verse.zipFile.CopyOfZipFileUtil.main(CopyOfZipFileUtil.java:303)
借助百度、⾕歌资料发现:
1、java解压⽂件有两种⽅式,⼀是⾃⼰写代码,⼆是调⽤压缩软件CMD执⾏
2、第⼆个错误是由于WinRAR5之后,在rar格式的基础上,推出了另⼀种rar,叫RAR5,⽽java-unrar解析不了这种格式
查看rar格式属性可以通过右键 —> 属性查看,如图
中文写代码软件
因此需要舍弃代码解压的⽅式,改为CMD调⽤的⽅式,虽然压缩软件有很多,但从⽹上能到执⾏命令的,也就WinRAR了,所以我们采⽤WinRAR5之后的版本解决,5之前的版本肯定是不⾏的了
使⽤cmd⽅式效果如何呢?既能解决中⽂乱码问题,⼜能解压RAR5压缩⽂件,⽽且代码量还更少了,⽀持的格式也更多了。
附上CMD⽅式调⽤代码:
  /**
* 采⽤命令⾏⽅式解压⽂件
* @param zipFile 压缩⽂件
* @param destDir 解压结果路径
* @return
*/
public static boolean realExtract(File zipFile, String destDir) {
// 解决路径中存在/..格式的路径问题
destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();
ains("..")) {
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;
}
}
}
// 获取的路径,放在java web⼯程下的WebRoot路径下
String classPath = "";
try {
classPath = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
// 兼容main⽅法执⾏和javaweb下执⾏
String winrarPath = (classPath.indexOf("WEB-INF") > -1 ? classPath.substring(0, classPath.indexOf("WEB-INF")) :            classPath.substring(0, classPath.indexOf("classes"))) + "/";
winrarPath = new File(winrarPath).getAbsoluteFile().getAbsolutePath();
System.out.println(winrarPath);
boolean bool = false;
if (!ists()) {
return false;
}
// 开始调⽤命令⾏解压,参数-o+是表⽰覆盖的意思
String cmd = winrarPath + " X -o+ " + zipFile + " " + destDir;
System.out.println(cmd);
try {
Process proc = Runtime().exec(cmd);
if (proc.waitFor() != 0) {
if (itValue() == 0) {
bool = false;
}
} else {
bool = true;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("解压" + (bool ? "成功" : "失败"));
return bool;
}