一、引入依赖
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.1</version>
</dependency>
二、使用添加文件(addFiles)的方式生成压缩包
/**
* @Author wangtw
* @Description 使用addFiles方式压缩文件
* @Date 07:34 2023/11/22
* @param fileList 需要压缩的文件列表
* @param zipPath zip包路径
* @param password zip包密码
* @return
**/
public static void zip(ArrayList<File> fileList, String zipPath, String password) {
ZipParameters parameters = new ZipParameters();
// 压缩方式
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if (StringUtils.hasText(password)) {
parameters.setEncryptFiles(true);
// 加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword(password.toCharArray());
}
try {
ZipFile zipFile = new ZipFile(zipPath);
zipFile.addFiles(fileList, parameters);
} catch (ZipException e) {
e.printStackTrace();
}
}
三、使用添加流(addStream)的方式生成压缩文件
/**
* @Author wangtw
* @Description 使用addStream方式压缩文件
* @Date 20:01 2023/11/22
* @param fileList 文件列比啊
* @param zipPath zip包路径
* @param password 密码
* @return
**/
public static void zipByInputStream(ArrayList<File> fileList, String zipPath, String password) throws ZipException, FileNotFoundException {
ZipFile zipFile = new ZipFile(zipPath);
for (File file : fileList) {
InputStream inputStream = new FileInputStream(file);
ZipParameters parameters = new ZipParameters();
// 压缩方式
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if (StringUtils.hasText(password)) {
parameters.setEncryptFiles(true);
// 加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword(password.toCharArray());
}
parameters.setSourceExternalStream(true);
parameters.setFileNameInZip(file.getName());
zipFile.addStream(inputStream, parameters);
// 关闭输入流
IOUtils.closeQuietly(inputStream);
}
}
四、向压缩包输出流(ZipOutputStream)中写入文件
1、示例代码
/**
* 压缩文件到输出流中
* @param fileList 文件列表
* @param outputStream 压缩包输出流
* @param password 压缩包密码
* @throws IOException
* @throws ZipException
*/
public static void zipOutputStream(ArrayList<File> fileList, OutputStream outputStream, String password) throws IOException, ZipException {
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
for (File file : fileList) {
ZipParameters parameters = new ZipParameters();
// 压缩方式
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if (StringUtils.hasText(password)) {
parameters.setEncryptFiles(true);
// 加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword(password.toCharArray());
}
parameters.setSourceExternalStream(true);
parameters.setFileNameInZip(file.getName());
zipOutputStream.putNextEntry(null, parameters);
InputStream inputStream = new FileInputStream(file);
byte[] bytes=new byte[1024 * 1024];
int len;
while((len = inputStream.read(bytes)) != -1){
zipOutputStream.write(bytes,0, len);
}
IOUtils.closeQuietly(inputStream);
zipOutputStream.closeEntry();
}
zipOutputStream.finish();
}
2、测试代码
@Test
public void zipOutputStreamTest() {
File fileone = new File("/Users/outenmon/workspace/idea_workspace/java/cento-practice/src/main/resources/io-test/test.txt");
File filetwo = new File("/Users/outenmon/workspace/idea_workspace/java/cento-practice/src/main/resources/application.yaml");
ArrayList<File> fileList = new ArrayList<>();
fileList.add(fileone);
fileList.add(filetwo);
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(new File(new Date().getTime() + ".zip"));
zipOutputStream(fileList, outputStream, "123456");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ZipException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(outputStream);
}
}
五、异常总结
1、net.lingala.zip4j.exception.ZipException: input file is null
需要把ZipParameters对象的isSourceExternalStream属性设置为true,例如:parameters.setSourceExternalStream(true);
2、net.lingala.zip4j.exception.ZipException: file name is empty for external stream
需要设置ZipParameters对象的fileNameInZip属性,例如:parameters.setFileNameInZip(file.getName());