因为jdk自带的zip不支持密码,所以使用第三方包
jar使用jdk1.8编译,但是兼容jdk1.7,部分功能可能会受影响,1.8以上正常
jar点我下载 zip4j.jar
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Zip4Util {
/**
* @author: bughz
* @description: 解压带密码的zip文件
* @createDate: 2022-07-11 09:40:01
* @param zipFilePath zip文件路径
* @param password 解密密码
* @param targetPath 解压路径
* @return void
*/
public static void UnzipByPassword(String zipFilePath,String password,String targetPath) throws ZipException {
new ZipFile(zipFilePath, password.toCharArray()).extractAll(targetPath);
}
/**
* @author: bughz
* @description: 解压zip文件
* @createDate: 2022-07-11 09:40:01
* @param zipFilePath zip文件路径
* @param targetPath 解压路径
* @return void
*/
public static void unzip(String zipFilePath,String targetPath) throws ZipException {
new ZipFile(zipFilePath).extractAll(targetPath);
}
/**
* @author: bughz
* @description: 压缩带密码的zip文件(zip标准加密),如果zipPath存在,则将后续文件添加进zipPath
* @createDate: 2022-07-11 09:43:07
* @param zipPath 压缩路径以及文件名
* @param password 加密密码
* @param filePaths 文件、多个,必传
* @return void
*/
public static void zipByPassword(String zipPath,String password,File... filePaths) throws ZipException {
if(filePaths==null || filePaths.length==0){
throw new ZipException("param(s) filePaths not null");
}
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
setFilesOrDirectorys(zipFile,filePaths);
}
/**
* @author: bughz
* @description: 压缩zip文件(zip标准加密),如果zipPath存在,则将后续文件添加进zipPath
* filePaths包含路径,打包时包含主目录例如 /app/test 打包后包含test
* @createDate: 2022-07-11 09:43:07
* @param zipPath 压缩路径以及文件名
* @param filePaths 文件、多个,必传
* @return void
*/
public static void zip(String zipPath,File... filePaths) throws ZipException {
if(filePaths==null || filePaths.length==0){
throw new ZipException("param(s) filePaths not null");
}
ZipFile zipFile = new ZipFile(zipPath);
setFilesOrDirectorys(zipFile,filePaths);
}
/**
* @author: bughz
* @description: 压缩zip文件(zip标准加密),如果zipPath存在,则将后续文件添加进zipPath
* filePaths不包含路径,打包时不包含主目录例如 /app/test 打包后主目录是test中的文件
* 多用于压缩目录
* @createDate: 2022-07-11 09:43:07
* @param zipPath 压缩路径以及文件名
* @param noIndexDir true不包含主目录 no @see com.bughz.util.Zip4Util.zip(String,File...)
* @param filePaths 文件、多个,必传
* @return void
*/
public static void zip(String zipPath,boolean noIndexDir,File... filePaths) throws ZipException {
if(filePaths==null || filePaths.length==0){
throw new ZipException("param(s) filePaths not null");
}
if(!noIndexDir){
zip(zipPath,filePaths);
}else{
List<File> files=new ArrayList<>();
for (File file:filePaths) {
if(!file.exists()){
continue;
}
if(file.isFile()){
files.add(file);
}else{
files.addAll(Arrays.asList(file.listFiles()));
}
}
ZipFile zipFile = new ZipFile(zipPath);
setFilesOrDirectorys(zipFile,files.toArray(new File[0]));
}
}
/**
* @author: bughz
* @description: 将文件流压缩为zip文件
* @createDate: 2022-09-05 08:50:56
* @param in 输入的文件
* @param fileName 被压缩文件的文件名
* @return java.io.InputStream
*/
public static InputStream zip(InputStream in,String fileName) {
return zip(new InputStream[]{in},new String[]{fileName});
}
public static InputStream zip(InputStream[] ins,String[] fileNames){
if(ins == null || ins.length == 0 || fileNames == null || fileNames.length == 0){
throw new BusinessException("文件和文件名不能为空");
}
if(ins.length!=fileNames.length){
throw new BusinessException("文件数量与文件名数量不匹配");
}
//创建ByteArrayOutputStream 存储压缩流,后期用于读出压缩文件流内容
ByteArrayOutputStream bos = new ByteArrayOutputStream();
java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(bos);
try {
for (int i = 0; i < ins.length; i++) {
//创建压缩文件内容实例,这里我就创建一个,
// 如果大家需要创建多个可多次putNextEntry
zos.putNextEntry(new java.util.zip.ZipEntry(fileNames[i]));
byte[] buffer = new byte[1024];
int len;
while ((len = ins[i].read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
//关闭流
ins[i].close();
}
zos.close();
return new ByteArrayInputStream(bos.toByteArray());
}catch (Exception e){
throw new BusinessException("压缩文件失败",e);
}
}
/**
* @author: bughz
* @description: 删除文件
* @createDate: 2022-07-11 09:51:29
* @param files
* @return void
*/
public static void deleteFile(File... files){
if (files == null) {
return;
}
for (File file:files) {
deleteDir(file);
}
}
private static void setFilesOrDirectorys(ZipFile zipFile,File... fileOrDirectorys) throws ZipException {
List<File> AllFiles=new ArrayList<>();
for (File fileOrDirectory:fileOrDirectorys) {
if(!fileOrDirectory.exists()){
continue;
}
if(fileOrDirectory.isFile()){
AllFiles.add(fileOrDirectory);
}else{
zipFile.addFolder(fileOrDirectory);
}
}
if(!AllFiles.isEmpty()){
zipFile.addFiles(AllFiles);
}
}
private static void deleteDir(File fileOrDirectory){
if(fileOrDirectory.isFile()){
fileOrDirectory.delete();
return;
}
//获取目录下所有文件和目录
File files[] = fileOrDirectory.listFiles();
for (File file : files) {
if(file.isDirectory()){
deleteDir(file);
}else {
file.delete();
}
}
//最终把该目录也删除
fileOrDirectory.delete();
}
/**
* @author: BUGHZ
* @description: 网络压缩文件解压到指定目录
* @createDate: 2023-05-18 10:45:25
* @param inputStream
* @param targetPath
* @return
*/
public static void unzip(InputStream inputStream,String targetPath) throws IOException {
ZipInputStream zin = new ZipInputStream(inputStream);
LocalFileHeader ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
} else {
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
byte[] byte_s=new byte[1024];
int num=-1;
while((num=zin.read(byte_s,0,byte_s.length))>-1){//通过read方法来读取文件内容
byteArrayOutputStream.write(byte_s,0,num);
}
FileCopyUtils.copy(byteArrayOutputStream.toByteArray(), new File(targetPath+"/"+ze.getFileName()));
}
}
}
}