package com.sg.test.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/***
* @date 2020/1/08
**/
public class ZipUtil {
private static final Logger logger = LoggerFactory.getLogger(ZipUtil.class);
/** 缓冲器大小*/
private static final int BUFFER = 4096;
public static void unzip(String zipFileName, String outputDirectory) {
try {
ZipFile zipFile = new ZipFile(new File(zipFileName), Charset.forName("GBK"));
OutputStream outputStream;
InputStream inputStream;
Enumeration<? extends ZipEntry> entries= zipFile.entries();
ZipEntry zn;
while (entries.hasMoreElements()) {
zn = entries.nextElement();
if (zn.isDirectory()) {
String name = zn.getName();
name = name.substring(0, name.length() - 1);
File f = new File(outputDirectory + File.separator + name);
f.mkdir();
logger.debug("mkdir " + outputDirectory + File.separator + name);
} else {
File f = new File(outputDirectory + File.separator + zn.getName());
f.createNewFile();
logger.debug("f:" + f);
outputStream = new FileOutputStream(f);
inputStream = zipFile.getInputStream(zn);
int size = 0;
byte[] buffer = new byte[BUFFER];
while ((size = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, size);
}
outputStream.flush();
inputStream.close();
outputStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 压缩方法
* (可以压缩空的子目录)
* @param srcPath 压缩源路径
* @param zipFileName 目标压缩文件
*/
public static boolean zip(String srcPath, String zipFileName) {
System.out.println("zip compressing...");
File srcFile = new File(srcPath);
//所有要压缩的文件
List<File> fileList = getAllFiles(srcFile);
//缓冲器
byte[] buffer = new byte[BUFFER];
ZipEntry zipEntry;
//每次读出来的长度
int readLength;
try {
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
for (File file : fileList) {
if (file.isFile()) {
zipEntry = new ZipEntry(getRelativePath(srcPath, file));
zipEntry.setSize(file.length());
zipEntry.setTime(file.lastModified());
zipOutputStream.putNextEntry(zipEntry);
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
while ((readLength = inputStream.read(buffer, 0, BUFFER)) != -1) {
zipOutputStream.write(buffer, 0, readLength);
}
inputStream.close();
System.out.println("file compressed: " + file.getCanonicalPath());
} else {//若是目录(即空目录)则将这个目录写入zip条目
zipEntry = new ZipEntry(getRelativePath(srcPath, file) + "/");
zipOutputStream.putNextEntry(zipEntry);
System.out.println("dir compressed: " + file.getCanonicalPath() + "/");
}
}
zipOutputStream.close();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.out.println("zip fail!");
return false;
}
System.out.println("zip success!");
return true;
}
/**
* 取的给定源目录下的所有文件及空的子目录
* 递归实现
* @param srcFile 文件
*/
private static List<File> getAllFiles(File srcFile) {
List<File> fileList = new ArrayList<>();
File[] tmp = srcFile.listFiles();
assert tmp != null;
for (File file : tmp) {
if (file.isFile()) {
fileList.add(file);
System.out.println("add file: " + file.getName());
}
if (file.isDirectory()) {
//若不是空目录,则递归添加其下的目录和文件
if (Objects.requireNonNull(file.listFiles()).length != 0) {
fileList.addAll(getAllFiles(file));
} else {//若是空目录,则添加这个目录到fileList
fileList.add(file);
System.out.println("add empty dir: " + file.getName());
}
}
}
return fileList;
}
/**
* 取相对路径
* 依据文件名和压缩源路径得到文件在压缩源路径下的相对路径
* @param dirPath 压缩源路径
* @param file 文件
* @return 相对路径
*/
private static String getRelativePath(String dirPath, File file) {
File dir = new File(dirPath);
StringBuilder relativePath = new StringBuilder(file.getName());
while (true) {
file = file.getParentFile();
if (file == null) {
break;
}
if (file.equals(dir)) {
break;
} else {
relativePath.insert(0, file.getName() + "/");
}
}
return relativePath.toString();
}
}
/**
* 删除文件夹下的所有文件
* @param fileDir 文件夹
*/
private static void deleteAllFiles(String fileDir) {
File file = new File(fileDir);
if (file.isFile()) {
file.delete();
} else {
File[] files = file.listFiles();
for (File f : files) {
deleteAllFiles(fileDir + File.separator + f.getName());
}
file.delete();
}
}
测试
//解压问价
@Test
public void unzip() {
String filePath = "F:\\新建文件夹";
String fileName = "file.zip";
ZipUtil.unzip(filePath + File.separator + fileName, filePath);
}
//压缩文件
@Test
public void zip() throws IOException {
String filePath = "F:\\新建文件夹";
String fileName = "file.zip";
ZipUtil.zip(filePath,filePath+File.separator+fileName);
}