解压zip跟rar压缩文件

时间:2022-09-13 11:50:28

这里是对zip及rar文件进行解压
需要注意的是,创建文件时注意linux跟windos的分隔符不太一样
下面 File.separator 是获取当前系统分隔符

解压zip需要引入ant.jar包,如下是maven引入配置

<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.0</version>
</dependency>

解压rar需要引入commons-logging.jar 与 junrar-0.7.jar 包,
依赖包下载

如下是maven引入配置

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>

<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>0.7</version>
</dependency>

下面是解压的代码,供大家参考

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import com.unionpay.common.util.StringUtil;
import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;

/**
* @author mszhou
*/

public class FileOperaction{

/**
* 解压文件
* @param fileName 需要解压的压缩文件路径
* @param outputDirectory 需要解压到的目录
* @param dirName 解压后文件夹需要重命名的名称
* @return 返回true表示成功
*/

public boolean unFile(String fileName,String outputDirectory,String dirName){

boolean flag =false;//默认失败

try{
String pName="";
if(fileName.toLowerCase().endsWith(".zip")){//zip压缩文件

pName=unZipFile(fileName,outputDirectory);

}else if(fileName.toLowerCase().endsWith(".rar")){//rar压缩文件

pName=unRarFile(fileName,outputDirectory);

}else{//不支持的压缩文件
return flag;
}

if(pName!=null&&!"".equals(pName)){

//============修改文件夹名称开始==================
File from = new File(outputDirectory+File.separator+pName);//旧文件夹
File to = new File(outputDirectory+File.separator+dirName);//新文件夹
if(to.exists()){//判断是否存在,存在先删除
deleteFile(to);//删除,这里调用下面的删除方法
}

if (from.renameTo(to)){//修改成功
flag=true;//设置成功标志
}
//============修改文件夹名称结束==================

}

}catch(Exception e){//异常

}

return flag;
}


/**
* 解压zip文件方法
* @param zipFilename 要解压的zip包文件
* @param outputDirectory 解压后存放的目录
* @return 返回解压后目录名称
* @throws Exception
*/

public String unZipFile(String zipFilename,String outputDirectory) throws Exception {

String strName="";//保存解压后的文件夹名称

File outFile = new File(outputDirectory);//创建指定解压后存放的目录对象
if(!outFile.exists()){//判断文件是否存在,不存在则先创建
outFile.mkdirs();//不存在则创建
}

ZipFile zipFile = new ZipFile(zipFilename);//创建对象

Enumeration en = zipFile.getEntries();

while (en.hasMoreElements()){//判断是否有下一个

ZipEntry zipEntry = (ZipEntry) en.nextElement();

if(zipEntry.isDirectory()){//表示是文件夹

String dirName = zipEntry.getName();//得到文件夹名称
dirName = dirName.substring(0,dirName.length()-1);//去掉后面的/ (如: jieya/ss/ ,去掉后面的/)

File f = new File(outFile.getPath() + File.separator + dirName);//创建文件夹对象
f.mkdirs();//创建文件夹

//判断是否是最上层目录(没有目录分割符表示最上层,如:jieya)
if(dirName.indexOf("/")<=0&&dirName.indexOf("\\")<=0){
strName=dirName;//保存解压后的文件夹名称(解压后文件夹目录名称)
}

}else{//表示是文件

File f = new File(outFile.getPath()+File.separator+zipEntry.getName());//创建文件对象

//========判断文件不存在的话,就创建该文件所在文件夹的目录 ==开始=======
if(!f.exists()){//
String[] arrFolderName = zipEntry.getName().split("/");
String strRealFolder = "";

for (int i = 0; i < (arrFolderName.length - 1); i++) {
strRealFolder += arrFolderName[i] + File.separator;
}

File tempDir = new File(outFile.getPath()+File.separator+strRealFolder);//创建文件夹目录对象
tempDir.mkdirs();//此处使用.mkdirs()方法,而不能用.mkdir()
}
//========判断文件不存在的话,就创建该文件所在文件夹的目录 ==结束=======

f.createNewFile();
InputStream in = zipFile.getInputStream(zipEntry);
FileOutputStream out = new FileOutputStream(f);

try {

int c;
byte[] by = new byte[1024];
while ((c = in.read(by)) != -1) {
out.write(by, 0, c);
}

} catch (IOException e) {
throw e;
} finally {
out.close();
in.close();
}

}

}
return strName;
}

/**
* 解压rar文件的方法
* @param rarFilename 需要解压的rar文件路径
* @param outputDirectory 解压后存放的目录
* @return 返回解压后目录名称
* @throws Exception
*/

public String unRarFile(String rarFilename,String outputDirectory) throws Exception {

String strName="";//保存解压后的文件夹名称

File dstDiretory = new File(outputDirectory);//创建指定解压后存放的目录对象

if(!dstDiretory.exists()){//判断文件是否存在,不存在则先创建
dstDiretory.mkdirs();//创建目录
}

Archive a = null;
try{
a = new Archive(new File(rarFilename));
if (a != null) {

FileHeader fh = a.nextFileHeader();

while (fh != null) {

//防止文件名中文乱码问题的处理
String dirName = fh.getFileNameW().isEmpty()?fh.getFileNameString():fh.getFileNameW();

if (fh.isDirectory()) {//表示是文件夹

String tmpUrl=outputDirectory+File.separator+dirName;

//该操作是将\分割符转换成当前系统的分割符,这操作是怕在linux系统中不识别\分割符
// windos系统分割符是\ , linux系统分隔符是 /
//如路径 C:\demo\tmp\dir 在windos下正常,在linux下就会出错
//在linux下C:\demo\tmp\dir转换后为 C:/demo/tmp/dir
if("/".equals(File.separator)){
tmpUrl=tmpUrl.replaceAll("\\\\",File.separator);
}

File fol = new File(tmpUrl);//创建文件对象
fol.mkdirs();//创建文件夹

//判断是否是最上层目录(没有目录分割符表示最上层,如:jieya)
if(dirName.indexOf("/")<=0&&dirName.indexOf("\\")<=0){

strName=dirName;//保存解压后的文件夹名称(解压后文件夹目录名称)

}

}else{//表示是文件

String tmpUrl=outputDirectory+File.separator+dirName.trim();

//该操作是将\分割符转换成当前系统的分割符,这操作是怕在linux系统中不识别\分割符
// windos系统分割符是\ , linux系统分隔符是 /
//如路径 C:\demo\tmp\dir 在windos下正常,在linux下就会出错
//在linux下C:\demo\tmp\dir转换后为 C:/demo/tmp/dir
if("/".equals(File.separator)){
tmpUrl=tmpUrl.replaceAll("\\\\",File.separator);
}

File out = new File(tmpUrl);//创建文件对象

FileOutputStream os=null;

try {

if (!out.exists()) {//判断文件是否存在

//判断文件所在的目录是否存在,不存在则先创建
if (!out.getParentFile().exists()) {
out.getParentFile().mkdirs();//创建目录
}
out.createNewFile();//创建文件
}
os = new FileOutputStream(out);

a.extractFile(fh,os);

}catch(Exception ex) {
ex.printStackTrace();
}finally{
os.close();
}
}

fh = a.nextFileHeader();
}
}
}catch(Exception e){
throw e;
}finally{
a.close();
}
return strName;
}

/**
* 删除文件方法
* @param file 表示要删除的文件对象
*/

private void deleteFile(File file){
if(file.exists()){//首先判断文件是否存在

if(file.isFile()){//判断是文件

file.delete();//删除文件

}else if(file.isDirectory()){//否则是目录

File files[] = file.listFiles();//获取该目录下的所有文件及目录

for(int i = 0; i < files.length; i++){//遍历

this.deleteFile(files[i]);//自己调用自己,迭代删除

}
}

file.delete();//最后删除剩余的空文件夹

}
}

}