import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
public class ZIPUtil {
public final static int BUFFER_SIZE = 1024 * 8;
/**
* 打成zip压缩包
* @param dirPath 源文件夹路径
* @param toZipPath 解压后存放文件目录
*/
public static void doZip(String dirPath, String toZipPath) {
File dir = null;
ZipOutputStream zipOut = null;
String zipDirName = ""; //存储生成的zip包的路径
String parentPath = null;
try {
dir = new File(dirPath);
zipDirName = getZipPath(dir.getName(), toZipPath);
parentPath = dir.getParent();
zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipDirName)));
doZipHandlerDir(dir, zipOut, parentPath);
zipOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获得zip存储路径
* @param dirName
* @param toZipPath
* @return
*/
private static String getZipPath(String dirName, String toZipPath) {
String zipDirName = "";
if (toZipPath != null && !"".equals(toZipPath.trim())) {
zipDirName = toZipPath + File.separator;
File newDir = new File(zipDirName);
if (!newDir.exists()) {
newDir.mkdirs();
}
}
zipDirName += dirName + ".zip";
return zipDirName;
}
/**
* 递归完成目录下文件读取
* @param dir
* @param zipOut
* @throws Exception
*/
private static void doZipHandlerDir(File dir, ZipOutputStream zipOut, String parentPath) throws Exception {
File[] files = dir.listFiles();//获得目录下的所有文件(包括目录和文件)
byte[] buffer = new byte[BUFFER_SIZE];//缓存大小
if (files.length == 0) {//如果目录为空另行创建
zipOut.putNextEntry(new ZipEntry(handlerFilePath(dir.toString(),parentPath)+File.separator));
zipOut.closeEntry();
} else {//如果目录下不为空 则分别处理目录和文件
for (File file : files) {
if (file.isDirectory()) {//目录情况递归遍历
doZipHandlerDir(file, zipOut, parentPath);
} else {//文件情况读文件 并写入到zip包中
doZipWriteFile(file, zipOut, parentPath, buffer);
}
}
}
}
/**
* 向zip包中写入文件
* @param file 文件对象
* @param zipOut zip输出流
* @param parentPath 父目录路径
* @param buffer 缓存
* @throws Exception 向上抛出异常
*/
private static void doZipWriteFile(File file, ZipOutputStream zipOut, String parentPath, byte[] buffer) throws Exception {
FileInputStream fis = new FileInputStream(file);
zipOut.putNextEntry(new ZipEntry(handlerFilePath(file.toString(), parentPath)));
int length = 0;//读取字节长度
while ((length = fis.read(buffer)) > 0) {
zipOut.write(buffer, 0, length);
}
zipOut.closeEntry();
fis.close();
}
/**
* 处理路径 将绝对路径处理成相对路径 否则zip包中会出现绝对路径下的每一层目录
* @param realPath 绝度路径
* @param parentPath 需要去掉的父路径
* @return 处理后的相对路径
* @throws Exception 找不到父路径时抛出异常
*/
private static String handlerFilePath(String realPath, String parentPath) throws Exception {
int index = -1;
index = realPath.indexOf(parentPath);
if (index == -1) {
throw new Exception("路径错误");
}
return realPath.substring(index + parentPath.length());
}
/**
* 解压缩文件
* @param unZipPath 要解压缩的zip文件路径 (路径+文件名)
* @param toUnZipPath 解压后存放的路径
*/
public static void unZip(String unZipPath, String toUnZipPath) {
ZipFile zipFile = null;
FileOutputStream outStream = null;
InputStream inputStream = null;
File file = null;
try {
zipFile = new ZipFile(unZipPath);
for (Enumeration entities = zipFile.getEntries(); entities.hasMoreElements();) {//遍历zip包下的zip条目
ZipEntry zipEntry = (ZipEntry) entities.nextElement();
file = new File(getUnZipPath(zipEntry.getName(), toUnZipPath));
mkdirs(zipEntry, file);
inputStream = zipFile.getInputStream(zipEntry);//从zip条目获得输入流
outStream = new FileOutputStream(file);//获得写入磁盘的输出流
write2Disk(outStream, inputStream);
}
zipFile.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (outStream != null) {
outStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 解压过程中创建目录
* @param zipEntry zip条目
* @param file 解压的文件夹或者文件
*/
private static void mkdirs(ZipEntry zipEntry, File file) {
if (zipEntry.isDirectory()) {
file.mkdirs();
} else {
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
}
}
/**
* 解压后写到磁盘
* @param outStream 输出流
* @param inputStream 读文件的输入流
* @throws IOException io异常
*/
private static void write2Disk(FileOutputStream outStream, InputStream inputStream) throws IOException {
int length = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((length = inputStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
outStream.flush();
outStream.close();
inputStream.close();
}
/**
* 获得解压后存放路径
* @param zipName zip条目名
* @param toUnZipPath 解压路径
* @return
*/
private static String getUnZipPath(String zipName, String toUnZipPath) {
String unZipPath = "";//解压后存储路径
if (toUnZipPath != null && !"".equals(toUnZipPath)) {
unZipPath = toUnZipPath + File.separator;
}
unZipPath += zipName;
return unZipPath;
}
public static void main(String[] args) {
unZip("C:/1.zip", "C:/123");
}
}