用JAVA解决压缩文件解压的两种方式:
(完整代码在文章末尾)
普遍的压缩文件的格式有.zip和.rar两种,我将分不同情况分别将这两种类型的压缩文件进行解压。
第一种:将.zip格式压缩包进行解压
1,首先我们根据压缩包所在原始路径,创建源文件
File sourceFile=new File(path);
2,创建根目录。为了确保根目录在运行之前是不存在的,我们要进行判断,如果它已经存在,就要删除它,直接使用delete方法只能删除空目录,当目录中有文件或其他内容时,就无法删除。所以我们要用到使用commons-io包提供的FileUtil工具类进行删除,可以自行下载。
![]()
//根目录
String sourceFileName=sourceFile.getName();
File rootDir=new File(sourceFile.getParent()+"\\"+sourceFileName.substring(0,sourceFileName.lastIndexOf(".")));
//判断根目录是否已经存在
if(rootDir.exists()) {
//rootDir.delete();//仅能删除空目录
//使用commons-io包提供的FileUtil工具类进行删除
try {
FileUtils.deleteDirectory(rootDir);
}catch(IOException e){
e.printStackTrace();
}
}
//创建根目录
rootDir.mkdir();
3,子目录以及子文件的创建。根目录创建完成后,我们要对压缩包中的子文件以及子目录进行创建,在读取压缩包内容时我们需要借助ZipInputStream方法用于进行zip格式的压缩文件输入流。由于无法确定根目录下为子文件还是子目录,同理,我们也要对子文件和子目录进行判断继而进行相应的创建操作。(注意:此时创建的子文件以及子目录并没有内容)
try(ZipInputStream in=new ZipInputStream(new FileInputStream(sourceFile))){
ZipEntry zipEntry=null;
while((zipEntry =in.getNextEntry())!=null) {
//创建子目录或子文件(File对象)
File file =new File(rootDir.getPath()+"\\"+zipEntry.getName());
if(zipEntry.isDirectory()) {
//物理磁盘创建了子目录
file.mkdir();
}else {
//物理磁盘创建了子文件
file.createNewFile();
4,将读取到的内容写入。确定好目录以及文件之后,我们要将相应的内容也写入创建的目录或者文件中。
try(FileOutputStream out=new FileOutputStream(file);){
byte[] buff=new byte[1024];
int len=-1;
while((len=in.read(buff))!=-1) {
out.write(buff,0,len);
}
}
此时,zip格式的压缩包就已经全部解压。
第二种:解压rar格式的压缩包
1-2步与第一种相同,创建根目录。
3,读取资源。这一步创建了Archive对象用来读取rar压缩文件
4.获取文件头列表并排序。这一步排序主要是因为从根目录到子目录子文件需要按照顺序依次写入,否则会出现写入子文件的时候发现并没有对应的目录,导致无法写入。
List<FileHeader>fileheaderList=archive.getFileHeaders();
fileheaderList.sort(new Comparator<FileHeader>(){
@Override
public int compare (FileHeader o1,FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
5.遍历文件头列表并解压缩。排序完成后就可以按照顺序遍历并依次写入内容。
遍历排序后的fileheaderList列表。
对于每个FileHeader对象fd,首先根据RAR中的文件名和根目录路径创建一个File对象f。
如果fd表示的是一个目录(通过fd.isDirectory()判断),则调用f.mkdir()创建该目录。
如果fd表示的是一个文件,则首先调用f.createNewFile()尝试创建文件(这一步其实可能不是必须的,因为FileUtils.copyInputStreamToFile在文件不存在时会创建它)。然后,通过archive.getInputStream(fd)获取文件的输入流,并使用FileUtils.copyInputStreamToFile方法将输入流的内容复制到新创建的文件中。
两种不同格式的压缩包解压完整代码:
package yuanjiuyuan.zmq.Io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FileUtils;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;
public class demo02 {
//将压缩包解压为同名文件
public static void main(String[] args) {
//String path="D:\\music\\tt\\easyftp-server-1.7.0.10-cn.zip";
String path="D:\\music\\tt\\实验案例.rar";
if (path.endsWith(".zip")){
unzip(path);
}else if(path.endsWith(".rar")) {
unrar(path);
}
}
//解压缩zip格式
public static void unzip(String path) {
//根据原始路径(字符串),创建源文件(File对象)
File sourceFile=new File(path);
//根目录
String sourceFileName=sourceFile.getName();
File rootDir=new File(sourceFile.getParent()+"\\"+sourceFileName.substring(0,sourceFileName.lastIndexOf(".")));
//判断根目录是否已经存在
if(rootDir.exists()) {
//rootDir.delete();//仅能删除空目录
//使用commons-io包提供的FileUtil工具类进行删除
try {
FileUtils.deleteDirectory(rootDir);
}catch(IOException e){
e.printStackTrace();
}
}
//创建根目录
rootDir.mkdir();
//ZipInputStream:用于进行Zip格式的压缩文件输入流
try(ZipInputStream in=new ZipInputStream(new FileInputStream(sourceFile))){
ZipEntry zipEntry=null;
while((zipEntry =in.getNextEntry())!=null) {
//创建子目录或子文件(File对象)
File file =new File(rootDir.getPath()+"\\"+zipEntry.getName());
if(zipEntry.isDirectory()) {
//物理磁盘创建了子目录
file.mkdir();
}else {
//物理磁盘创建了子文件
file.createNewFile();
//写入操作
try(FileOutputStream out=new FileOutputStream(file);){
byte[] buff=new byte[1024];
int len=-1;
while((len=in.read(buff))!=-1) {
out.write(buff,0,len);
}
}
}
}
}catch(IOException e) {
e.printStackTrace();
}
}
//解压缩rar格式
public static void unrar(String path) {
//1.创建解压缩的根目录
File rarFile=new File(path);
File rootDir=new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
//判断根目录是否已经存在
if(rootDir.exists()) {
//rootDir.delete();//仅能删除空目录
//使用commons-io包提供的FileUtil工具类进行删除
try {
FileUtils.deleteDirectory(rootDir);
}catch(IOException e){
e.printStackTrace();
}
}
//创建根目录
rootDir.mkdir();
//1.创建Archine对象,用于读取rar压缩文件格式
try(Archive archive=new Archive(new FileInputStream(path))){
List<FileHeader>fileheaderList=archive.getFileHeaders();
fileheaderList.sort(new Comparator<FileHeader>(){
@Override
public int compare (FileHeader o1,FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
for(FileHeader fd:fileheaderList) {
File f=new File(rootDir.getPath()+"\\"+fd.getFileName());
if(fd.isDirectory()) {
f.mkdir();
}else {
f.createNewFile();
InputStream in=archive.getInputStream(fd);
FileUtils.copyInputStreamToFile(in,f);
}
}
}catch(RarException|IOException e) {
e.printStackTrace();
}
}
}
如有错误或者补充,欢迎评论区留言。
883





