package decompress;
import java.io.File;
import java.io.FileOutputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import de.innosystec.unrar.Archive;
import de.innosystec.unrar.rarfile.FileHeader;
public class DeCompressUtil {
/**
* 解压zip格式压缩包
* 对应的是ant.jar
*/
private static void unzipString sourceZip,String destDir) throws Exception{
try{
Project p = new Project);
Expand e = new Expand);
e.setProjectp);
e.setSrcnew FilesourceZip));
e.setOverwritefalse);
e.setDestnew FiledestDir));
/*
ant下的zip工具默认压缩编码为UTF-8编码,
而winRAR软件压缩是用的windows默认的GBK或者GB2312编码
所以解压缩时要制定编码格式
*/
e.setEncoding"gbk");
e.execute);
}catchException e){
throw e;
}
}
/**
* 解压rar格式压缩包。
* 对应的是java-unrar-0.3.jar,但是java-unrar-0.3.jar又会用到commons-logging-1.1.1.jar
*/
private static void unrarString sourceRar,String destDir) throws Exception{
Archive a = null;
FileOutputStream fos = null;
try{
a = new Archivenew FilesourceRar));
FileHeader fh = a.nextFileHeader);
whilefh!=null){
if!fh.isDirectory)){
//1 根据不同的操作系统拿到相应的 destDirName 和 destFileName
String compressFileName = fh.getFileNameString).trim);
String destFileName = "";
String destDirName = "";
//非windows系统
ifFile.separator.equals"/")){
destFileName = destDir + compressFileName.replaceAll"\\", "/");
destDirName = destFileName.substring0, destFileName.lastIndexOf"/"));
//windows系统
}else{
destFileName = destDir + compressFileName.replaceAll"/", "\\");
destDirName = destFileName.substring0, destFileName.lastIndexOf"\"));
}
//2创建文件夹
File dir = new FiledestDirName);
if!dir.exists)||!dir.isDirectory)){
dir.mkdirs);
}
//3解压缩文件
fos = new FileOutputStreamnew FiledestFileName));
a.extractFilefh, fos);
fos.close);
fos = null;
}
fh = a.nextFileHeader);
}
a.close);
a = null;
}catchException e){
throw e;
}finally{
iffos!=null){
try{fos.close);fos=null;}catchException e){e.printStackTrace);}
}
ifa!=null){
try{a.close);a=null;}catchException e){e.printStackTrace);}
}
}
}
/**
* 解压缩
*/
public static void deCompressString sourceFile,String destDir) throws Exception{
//保证文件夹路径最后是"/"或者""
char lastChar = destDir.charAtdestDir.length)-1);
iflastChar!='/'&&lastChar!='\'){
destDir += File.separator;
}
//根据类型,进行相应的解压缩
String type = sourceFile.substringsourceFile.lastIndexOf".")+1);
iftype.equals"zip")){
DeCompressUtil.unzipsourceFile, destDir);
}else iftype.equals"rar")){
DeCompressUtil.unrarsourceFile, destDir);
}else{
throw new Exception"只支持zip和rar格式的压缩包!");
}
}
}
RAR压缩算法是不公开的,所以这方面的开源项目不多
幸好有一个叫unrar的开源项目支持RAR的解压,但不能压缩RAR文件
不过,直接使用unrar却不能支持带密码的RAR文件解压,经过多方查找,终于在Google Code上面找到一个支持密码的unrar版本,下载地址:http://code.google.com/p/java-unrar/
该项目依赖Jar包:
commons-logging.jar 比较常用,可以到Apache官网下载
gnu-crypto.jar 可以在http://www.gnu.org/software/gnu-crypto/下载
下面是一个简单的解压示例:
package com.reyo.demo.rar;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import de.innosystec.unrar.Archive;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.rarfile.FileHeader;
/**
* RAR格式压缩文件解压工具类
* 不支持RAR格式压缩
* 支持中文,支持RAR压缩文件密码
* 依赖jar包
* commons-io.jar
* commons-logging.jar
* java-unrar-decryption-supported.jar
* gnu-crypto.jar
*
* @author ninemax
*/
public class RarDecompressionUtil {
public static final String SEPARATOR = File.separator;
// =============================== RAR Format ================================
/**
* 解压指定RAR文件到当前文件夹
* @param srcRar 指定解压
* @param password 压缩文件时设定的密码
* @throws IOException
*/
public static void unrarString srcRar, String password) throws IOException {
unrarsrcRar, null, password);
}
/**
* 解压指定的RAR压缩文件到指定的目录中
* @param srcRar 指定的RAR压缩文件
* @param destPath 指定解压到的目录
* @param password 压缩文件时设定的密码
* @throws IOException
*/
public static void unrarString srcRar, String destPath, String password) throws IOException {
File srcFile = new FilesrcRar);
if !srcFile.exists)) {
return;
}
if null == destPath || destPath.length) == 0) {
unrarsrcFile, srcFile.getParent), password);
return;
}
unrarsrcFile,destPath, password);
}
/**
* 解压指定RAR文件到当前文件夹
* @param srcRarFile 解压文件
* @param password 压缩文件时设定的密码
* @throws IOException
*/
public static void unrarFile srcRarFile, String password) throws IOException {
if null == srcRarFile || !srcRarFile.exists)) {
throw new IOException”指定文件不存在.”);
}
unrarsrcRarFile, srcRarFile.getParent),password);
}
/**
* 解压指定RAR文件到指定的路径
* @param srcRarFile 需要解压RAR文件
* @param destPath 指定解压路径
* @param password 压缩文件时设定的密码
* @throws IOException
*/
public static void unrarFile srcRarFile, String destPath, String password) throws IOException {
if null == srcRarFile || !srcRarFile.exists)) {
throw new IOException”指定压缩文件不存在.”);
}
if !destPath.endsWithSEPARATOR)) {
destPath += SEPARATOR;
}
Archive archive = null;
OutputStream unOut = null;
try {
archive = new ArchivesrcRarFile, password, false);
FileHeader fileHeader = archive.nextFileHeader);
whilenull != fileHeader) {
if !fileHeader.isDirectory)) {
// 1 根据不同的操作系统拿到相应的 destDirName 和 destFileName
String destFileName = “”;
String destDirName = “”;
if SEPARATOR.equals”/”)) { // 非windows系统
destFileName = destPath + fileHeader.getFileNameW)).replaceAll”\\“, “/”);
destDirName = destFileName.substring0, destFileName.lastIndexOf”/”));
} else { // windows系统
destFileName = destPath + fileHeader.getFileNameW)).replaceAll”/”, “\\“);
destDirName = destFileName.substring0, destFileName.lastIndexOf”\”));
}
// 2创建文件夹
File dir = new FiledestDirName);
if !dir.exists) || !dir.isDirectory)) {
dir.mkdirs);
}
// 抽取压缩文件
unOut = new FileOutputStreamnew FiledestFileName));
archive.extractFilefileHeader, unOut);
unOut.flush);
unOut.close);
}
fileHeader = archive.nextFileHeader);
}
archive.close);
} catch RarException e) {
e.printStackTrace);
} finally {
IOUtils.closeQuietlyunOut);
}
}
}
