Java压缩和解压缩(二)Zip4j实践
Java压缩和解压缩admin 发布于:2023-03-05 00:28:26
阅读:loading
Zip4j-用于zip文件/流的Java库,作用于zip文件或流的最全面的Java库,它还支持zip加密和解密,使得处理zip文件/流的代码实现更加容易,甚至可以是一行代码【项目作者非常谦虚的认为没有冒犯到Java的内置zip实现】,这个库的主要目标是为所有人提供一个简单的API zip文件或流,常见操作是在库中执行繁重的操作,而不需要开发人员担心除了可用性之外,这个库的另一个重要目标是为尽可能多的zip功能,有以下几个特征(翻译于Github上的项目主页https://github.com/srikanth-lingala/zip4j):
(1)创建、添加、提取、更新、从zip文件中删除文件;
(2)支持流(ZipInputStream和ZipOutputStreat);
(3)读/写受密码保护的zip文件和流;
(4)支持AES和zip标准加密方法;
(5)支持Zip64格式;
(6)储存(无压缩)和放气压缩方法;
(7)从分割的zip文件(例如:z01、z02、…zip)创建或提取文件;
(8)支持压缩文件中的Unicode文件名和注释;
(9)进度监视器-用于集成到应用程序和面向用户的应用程序;
所以,它被评为用于zip文件的最佳Java库,甚至被誉为地表最强的Java操作zip库。
package cn.chendd.compress;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.UnzipParameters;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* zip4j组件的压缩和解压缩
*
* @author chendd
* @date 2023/3/5 8:08
*/
public class CompressZip {
/**
* 压缩zip文件
* @param outZipFile 源文件(夹)
* @param file 输出zip文件
* @param charset 字符编码
* @param password 密码
* @param comment 备注
*/
public static void zip(File file, File outZipFile, Charset charset, String password, String comment) {
if (outZipFile == null || file == null) {
return;
}
ZipParameters parameter = new ZipParameters();
//压缩方式,使用JDK内置zip
parameter.setCompressionMethod(CompressionMethod.DEFLATE);
ZipFile zipFile = new ZipFile(outZipFile);
//如果编码不为空,则设置编码
if (charset != null) {
zipFile.setCharset(charset);
}
//如果密码不为空,则设置密码
if (StringUtils.isNotEmpty(password)) {
//压缩方式为标准压缩
parameter.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
parameter.setEncryptFiles(true);
zipFile.setPassword(password.toCharArray());
}
if (!file.exists()) {
return;
}
try {
//根据文件或文件夹进行压缩
if (file.isFile()) {
zipFile.addFile(file, parameter);
} else if (file.isDirectory()) {
zipFile.addFolder(file, parameter);
}
//设置注释
if (StringUtils.isNotEmpty(comment)) {
zipFile.setComment(comment);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 压缩zip文件
* @param file 源文件(夹)
* @param outZipFile 输出zip文件
*/
public static void zip(File file, File outZipFile) {
zip(file, outZipFile, Charset.forName("GBK"), null, null);
}
/**
* 解压缩zip文件
* @param inZipFile 压缩文件
* @param file 文件
* @param charset 编码
* @param password 密码
*/
public static void unzip(File inZipFile, File file, Charset charset, String password) {
if (inZipFile == null || file == null) {
throw new NullPointerException("文件不能为空");
}
try {
if (!inZipFile.exists()) {
throw new FileNotFoundException(inZipFile.getAbsolutePath());
}
ZipFile zipFile = new ZipFile(inZipFile);
if (charset != null) {
zipFile.setCharset(charset);
}
if (!zipFile.isValidZipFile()) {
throw new IllegalArgumentException("zip文件格式不正确");
}
if (zipFile.isEncrypted()) {
if (StringUtils.isEmpty(password)) {
throw new NullPointerException("解压密码不能为空");
}
zipFile.setPassword(password.toCharArray());
}
UnzipParameters parameter = new UnzipParameters();
zipFile.extractAll(file.getAbsolutePath() , parameter);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 解压缩文件
* @param zipFile 压缩包文件
* @param file 文件
*/
public static void unzip(File zipFile , File file) {
unzip(zipFile , file, Charset.forName("GBK"), null);
}
/**
* 预览压缩包文件
* @param zipFile 压缩包文件
* @param charset 编码
* @return 文件列表(不含子层文件夹(夹))
*/
public static List<View> view(File zipFile, Charset charset) {
ZipFile outZipFile = new ZipFile(zipFile);
if (charset != null) {
outZipFile.setCharset(charset);
}
List<FileHeader> fileHeaders;
try {
fileHeaders = outZipFile.getFileHeaders();
List<View> resultList = new ArrayList<>();
for (FileHeader header : fileHeaders) {
View item = new View();
item.setFileName(header.getFileName());
item.setCompressedSize(header.getCompressedSize());
item.setUncompressedSize(header.getUncompressedSize());
item.setDirectory(header.isDirectory());
item.setLastModifiedTime(header.getLastModifiedTime());
resultList.add(item);
}
return resultList;
} catch (ZipException e) {
throw new RuntimeException(e);
}
}
/**
* 预览压缩包文件
* @param zipFile 压缩包文件
* @return 文件列表(不含子层文件夹(夹))
*/
public static List<View> view(File zipFile) {
return view(zipFile, Charset.forName("GBK"));
}
}
package cn.chendd.compress;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 预览文件对象
*
* @author chendd
* @date 2023/3/5 8:19
*/
@Data
public class View {
/**
* 文件名称
*/
private String fileName;
/**
* 压缩前大小
*/
private long compressedSize;
/**
* 压缩后大小
*/
private long uncompressedSize;
/**
* 是否为文件夹
*/
private boolean directory;
/**
* 最后修改时间
*/
private long lastModifiedTime;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
package cn.chendd.compress;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.MethodSorters;
import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
/**
* zip4j组件的压缩和解压缩测试
*
* @author chendd
* @date 2023/3/5 8:38
*/
@RunWith(JUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CompressZipTest {
/**
* 测试压缩文件
*/
@Test
public void toZipA() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/哈喽.txt");
File zipFile = new File(projectHome , "压缩文件夹/zip4j_哈喽.zip");
CompressZip.zip(file , zipFile);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试压缩文件夹
*/
@Test
public void toZipB() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/简单文件夹");
File zipFile = new File(projectHome , "压缩文件夹/zip4j_简单文件夹.zip");
CompressZip.zip(file , zipFile);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试多参数的压缩
*/
@Test
public void toZipC() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/简单文件夹");
File zipFile = new File(projectHome , "压缩文件夹/zip4j_多参数_简单文件夹.zip");
CompressZip.zip(file , zipFile , Charset.forName("GBK") , "https://www.chendd.cn" , "密码为:https://www.chendd.cn");
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 解压缩文件
*/
@Test
public void unZipA() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/zip4j_哈喽.zip");
File file = new File(projectHome , "解压缩文件夹/zip4j_哈喽");
CompressZip.unzip(zipFile , file);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 解压缩文件夹
*/
@Test
public void unZipB() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/zip4j_简单文件夹.zip");
File file = new File(projectHome , "解压缩文件夹/zip4j_简单文件夹");
CompressZip.unzip(zipFile , file);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 解压缩文件夹,包含多个参数
*/
@Test
public void unZipC() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/zip4j_多参数_简单文件夹.zip");
File file = new File(projectHome , "解压缩文件夹/zip4j_多参数_简单文件夹");
CompressZip.unzip(zipFile , file , Charset.forName("GBK") , "https://www.chendd.cn");
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
@Test
public void view() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/zip4j_多参数_简单文件夹.zip");
System.out.println("预览压缩包的文件:");
List<View> list = CompressZip.view(zipFile);
list.forEach(System.out::println);
}
}
(压缩/解压缩文件结构)
(带密码压缩文件和备注)
(1)本文使用开源项目zip4j实现的zip文件(夹)的压缩和解压缩,代码实现比前篇的基于JDK内置的API更加便捷和强大;
(2)本文示例包含文件压缩、文件解压缩、文件夹压缩、文件夹解压缩、压缩包文件列表预览;
(4)支持压缩文件的“注释说明”,支持压缩文件(夹)包含中文名称,支持压缩文件的密码压缩和解压缩;
(5)以上代码为示例代码,切勿直接使用:组件版本升级后ZipFile等对象需要close,所以上述的代码应该使用try-with-resource的写法来关闭IO;
(6)项目源码下载:源码下载.txt;
点赞