#Apache Commons Compress介绍-Zip压缩解压
简述
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
/**
* @description:
* @author: jiazefeng
* @date: Created in 2022/06/26 上午 10:20
* @version:
* @modified By:
*/
public class ZipUtilApache {
/**
* 压缩文件
*
* @param sourceFiles 原文件数据集
* @param zipFile 压缩后的文件地址
* @throws Exception
*/
public static String doZip(List<String> sourceFiles, String zipFile) {
File zip = new File(zipFile);
if (!zip.getParentFile().exists()) {
zip.getParentFile().mkdirs();
}
try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(zip)) {
//ZipArchiveOutputStream(File file) :根据文件构建压缩输出流,将源文件压缩到此文件.
//setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。
// Zip64Mode 枚举有 3 个值:Always:对所有条目使用 Zip64 扩展、Never:不对任何条目使用Zip64扩展、AsNeeded:对需要的所有条目使用Zip64扩展
outputStream.setUseZip64(Zip64Mode.AsNeeded);
for (String sourceFile : sourceFiles) {
File file = new File(sourceFile);
//将每个源文件用 ZipArchiveEntry 实体封装,然后添加到压缩文件中. 这样将来解压后里面的文件名称还是保持一致.
ZipArchiveEntry entry = new ZipArchiveEntry(file.getName());
// 可以设置压缩等级
outputStream.setLevel(5);
// 可以设置压缩算法,当前支持ZipEntry.DEFLATED和ZipEntry.STORED两种
outputStream.setMethod(ZipEntry.DEFLATED);
// 也可以为每个文件设置压缩算法
entry.setMethod(ZipEntry.DEFLATED);
// 在zip中创建一个文件
outputStream.putArchiveEntry(entry);
try (InputStream inputStream = new FileInputStream(file)) {
byte[] buffer = new byte[1024 * 5];
int length = -1;//每次读取的字节大小。
while ((length = inputStream.read(buffer)) != -1) {
//把缓冲区的字节写入到 ZipArchiveEntry
outputStream.write(buffer, 0, length);
}
// 完成一个文件的写入
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
outputStream.closeArchiveEntry(); //写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常
outputStream.finish();//压缩结束.
} catch (Exception e) {
return null;
}
return zipFile;
}
/**
* 解压zip
*
* @param zipPath zip文件路径 必传
* @param saveFilePath 如果为空那么解压到zipPath的当前目录,不为空解压到指定目录
*/
public static void unZip(String zipPath, String saveFilePath) {
try {
//保存解压文件目录
if (StringUtils.isNotBlank(saveFilePath)) {
saveFilePath = new File(saveFilePath) + File.separator;
} else {
saveFilePath = new File(zipPath).getParent() + File.separator;
}
File zip = new File(zipPath);
ZipFile zipFile = new ZipFile(zip);
byte[] buffer = new byte[4096];
ZipArchiveEntry entry;
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); // 获取全部文件的迭代器
while (entries.hasMoreElements()) {
entry = entries.nextElement();
if (entry.isDirectory()) {
continue;
}
File outputFile = new File(saveFilePath + entry.getName());
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
try (InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(outputFile)) {
while (inputStream.read(buffer) > 0) {
fos.write(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SpringBootTest
public class ZipUtilTest {
@Test
public void testDoZip() {
List<String> fileList = new ArrayList<>();
fileList.add("D:\\Java 最常见 200+ 面试题全解析:面试必备.pdf");
fileList.add("D:\\2019年一些前端的面试题(含答案) - 简书.pdf");
fileList.add("D:\\前端面试题(2019篇)附答案-黑马程序员技术交流社区.pdf");
fileList.add("D:\\尚飞家长会《我们不一样,我们都很棒》2019.11.11.pptx");
fileList.add("D:\\Java笔试题.docx");
ZipUtilApache.doZip(fileList, "D:\\zip\\测试ZIP压缩.zip");
}
@Test
public void testUnZip(){
ZipUtilApache.unZip("D:\\zip\\手动压缩测试.zip","D:\\zip\\out");
}
}