Java IO库提供了对ZIP解压缩的支持,主要通过java.util.zip包中的类来实现。
ZipEntry:表示ZIP文件中的一个条目,可以是文件或目录。
ZipInputStream:用于进行zip格式的压缩文件输入流。ZipOutputStream:用于进行zip格式的压缩文件输出流。
对ZIP格式的文件进行解压
在解压缩zip格式文件时,首先,根据原始路径(字符串),创建源文件(File对象);其次创建根目录,在创建时如果根目录存在,则删除(借助第三方commons-io包提供的FileUtils工具类进行删除);接着,遍历压缩包中的每个子目录或子文件(zipEntry类型的对象),判断zipEntry是否为空,如果不为空则创建子目录或子文件(File对象);最后,读取当前压缩包中的子文件,并通过输出流out写入新子文件中。
package com.yym.zip.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FileUtils;
public class Test02 {
public static void main(String[] args) {
String path ="F:\\Test\\IOzip\\apache-jmeter-5.6.3.zip";
// String path="F:\\Test\\IOzip\\实验案例.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包提供的FileUtils工具类进行删除
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
// 创建根目录
rootDir.mkdir();
// ZipInputstream:用于进行zip格式的压缩文件输入流
try (ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile))) {
// 遍历压缩包中的每个子目录或子文件(zipEntry类型的对象)
ZipEntry zipEntry = null;
while((zipEntry = in.getNextEntry()) != null) {
// System.out.println(zipEntry.getName());
// 创建子目录或子文件(File对象)
File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());
if(zipEntry.isDirectory()) {
// 物理磁盘创建新子目录
file.mkdir();
}else {
// 物理磁盘创建新子文件
file.createNewFile();
// 读取当前压缩包中的子文件,并通过输出流out写入新子文件中
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 (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:
对RAR格式的文件进行解压
在解压缩rar格式文件时需导入第三方junrar-7.5.5.jar和slf4j-api-2.0.13.jar包,首先,根据原始路径(字符串),创建源文件(File对象);其次创建根目录,在创建时如果根目录存在,则删除(借助第三方commons-io包提供的FileUtils工具类进行删除);接着,创建Archive对象,用于读取rar压缩文件格式,获取压缩文件中的所有子目录或子文件(FileHeader对象) 按照子目录(子文件)名称排序;最后,创建新子目录和子文件,获取压缩包中的子文件输入流,复制文件输入流至新子文件。
package com.yym.zip.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
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 Test02 {
public static void main(String[] args) {
// String path ="F:\\Test\\IOzip\\apache-jmeter-5.6.3.zip";
String path="F:\\Test\\IOzip\\实验案例.rar";
if (path.endsWith(".zip")) {
unzip(path);
}else if (path.endsWith(".rar")) {
unrar(path);
}
}
// 解压缩rar格式
public static void unrar(String path) {
// 根据原始路径(字符串),创建源文件(File对象)
File rarFile = new File(path);
File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
if (rootDir.exists()) {
// 使用commons-io包提供的FileUtils工具类进行删除
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
// 创建根目录
rootDir.mkdir();
// 创建Archive对象,用于读取rar压缩文件格式
try(Archive archive = new Archive(new FileInputStream(path))){
// 获取压缩文件中的所有子目录或子文件(FileHeader对象)
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();
}
}
}
运行结果:
对ZIP格式的文件进行压缩
首先,获取所在目录,获取所有原始子文件;其次,创建zip压缩文件的输出流,遍历所有原始子文件,写入一个压缩包中的子文件(zipEntry对象),写入字节内容;最后,关闭压缩包中的子文件。
package com.yym.zip.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Test05 {
public static void main(String[] args) {
// 所在目录
File dir = new File("F:\\Test\\IOzip\\id");
// 获取所有原始子文件
File[] files = dir.listFiles();
// 创建zip压缩文件的输出流
try (ZipOutputStream out = new ZipOutputStream(
new FileOutputStream(dir.getPath()+"\\"+dir.getName()+".zip"))) {
// 遍历所有原始子文件
for(File f : files) {
// 写入一个压缩包中的子文件(zipEntry对象)
out.putNextEntry(new ZipEntry(f.getName()));
// 写入字节内容
out.write(Files.readAllBytes(f.toPath()));
// 关闭压缩包中的子文件
out.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果: