import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
/**
* @author leo
* @date 2021/12/15 16:29
*/
public class ZipUtils {
private static final Logger log = LoggerFactory.getLogger(ZipUtils.class);
public static void main(String[] args) {
// zipFile("D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30", "D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30.zip");
createZip("D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30", "D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30.zip");
unzipFile(new File("D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30.zip"), "D:\\tomcat8\\tomcat8084\\temp\\leo_2020-09-01_2020-09-30");
}
private static ZipArchiveInputStream getZipFile(File zipFile) throws Exception {
// encoding 需要注意
return new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipFile)), "GBK", true);
}
/**
* 解压文件
* @param zipFile 压缩包
* @param descDir 解压出来的文件存放目录
*/
public static void unzipFile(File zipFile, String descDir) {
try (ZipArchiveInputStream inputStream = getZipFile(zipFile)) {
File pathFile = new File(descDir);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
ZipArchiveEntry entry;
while ((entry = inputStream.getNextZipEntry()) != null) {
String entryName = entry.getName();
if (entry.isDirectory()) {
File directory = new File(descDir, entryName);
directory.mkdirs();
} else {
OutputStream os = null;
try {
if(entryName.contains("/")){
// 带目录的,先创建目录
String[] split = entryName.split("/");
String dirs = "";
for (int i = 0; i < split.length - 1; i++) {
dirs = dirs + split[i] + File.separator;
}
File directory = new File(descDir, dirs);
directory.mkdirs();
entryName = split[split.length -1];
os = new BufferedOutputStream(new FileOutputStream(new File(directory.getPath(), entryName)));
}else{
os = new BufferedOutputStream(new FileOutputStream(new File(descDir, entryName)));
}
IOUtils.copy(inputStream, os);
} finally {
IOUtils.closeQuietly(os);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建ZIP文件
* @param sourcePath 文件或文件夹路径
* @param zipPath 生成的zip文件存在路径(包括文件名)
*/
public static void createZip(String sourcePath, String zipPath) {
FileOutputStream fos = null;
ZipOutputStream zos = null;
try {
fos = new FileOutputStream(zipPath);
zos = new ZipOutputStream(fos);
writeZip(new File(sourcePath), "", zos, false);
} catch (FileNotFoundException e) {
log.error("创建ZIP文件失败",e);
} finally {
try {
if (zos != null) {
zos.close();
}
if(null != fos){
fos.close();
}
} catch (IOException e) {
log.error("创建ZIP文件失败",e);
}
}
}
/**
* 压缩文件
* @param file 待压缩的目录或文件
* @param parentPath 压缩文件内的目录
* @param zos 输出流
* @param needAppend 是否需要创建顶层目录
*/
private static void writeZip(File file, String parentPath, ZipOutputStream zos, boolean needAppend) {
if(file.exists()){
if(file.isDirectory()){
// 处理文件夹
if(needAppend){
// 需要拼接目录
parentPath += file.getName() + File.separator;
}
File [] files = file.listFiles();
if(files.length != 0){
for(File f : files){
writeZip(f, parentPath, zos, true);
}
}else{
// 空目录则创建当前目录
try {
zos.putNextEntry(new ZipEntry(parentPath));
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
ZipEntry ze = new ZipEntry(parentPath + file.getName());
zos.putNextEntry(ze);
byte [] content=new byte[1024];
int len;
while((len = fis.read(content)) != -1){
zos.write(content,0,len);
zos.flush();
}
} catch (FileNotFoundException e) {
log.error("创建ZIP文件失败",e);
} catch (IOException e) {
log.error("创建ZIP文件失败",e);
}finally{
try {
if(fis != null){
fis.close();
}
}catch(IOException e){
log.error("创建ZIP文件失败",e);
}
}
}
}
}
/**
* 压缩文件
* @param sourceFileName 等待压缩的文件或文件夹(含目录) D:\tomcat8\tomcat8084\temp\leo_2020-09-01_2020-09-30
* @param targetFile 生成压缩文件名(含目录) D:\tomcat8\tomcat8084\temp\leo_2020-09-01_2020-09-30.zip
* @throws Exception
*/
private static void zipFile(String sourceFileName, String targetFile) {
ZipOutputStream out = null;
BufferedOutputStream bos = null;
try{
// 创建zip输出流
out = new ZipOutputStream( new FileOutputStream(targetFile));
// 创建缓冲输出流
bos = new BufferedOutputStream(out);
File sourceFile = new File(sourceFileName);
// 调用函数
compress(out,bos,sourceFile,sourceFile.getName());
}catch (Exception e){
e.printStackTrace();
} finally {
try {
if(null != bos){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != out){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 压缩文件或目录
* @param out
* @param bos
* @param sourceFile
* @param base
* @throws Exception
*/
private static void compress(ZipOutputStream out, BufferedOutputStream bos, File sourceFile, String base) throws Exception{
// 如果路径为目录(文件夹)
if(sourceFile.isDirectory()){
// 取出文件夹中的文件(或子文件夹)
File[] flist = sourceFile.listFiles();
if(flist.length==0){
// 如果文件夹为空,则只需在目的地zip文件中写入一个目录进入点
try{
out.putNextEntry( new ZipEntry(base + "/"));
}catch (ZipException e){
if(e.getMessage().contains("duplicate entry")){
// 重复文件名,把文件名加后缀
String newBase = base + "_2";
out.putNextEntry(new ZipEntry(newBase + "/"));
}else {
e.printStackTrace();
}
}
} else {
// 如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
for(int i=0;i<flist.length;i++){
compress(out, bos, flist[i], flist[i].getName());
}
}
}else {
// 如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
try{
out.putNextEntry( new ZipEntry(base));
}catch (ZipException e){
if(e.getMessage().contains("duplicate entry")){
// 重复文件名,把文件名加后缀
String[] split = base.split("\\.");
String newBase = split[0] + "_2." + split[1];
out.putNextEntry( new ZipEntry(newBase));
}else {
e.printStackTrace();
}
}
FileInputStream fos = new FileInputStream(sourceFile);
BufferedInputStream bis = new BufferedInputStream(fos);
int tag;
// 将源文件写入到zip文件中
while((tag = bis.read()) != -1) {
bos.write(tag);
}
bos.flush();
bis.close();
fos.close();
}
}
}
05-29
1663
