java zip 壓縮與解壓
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.apache.commons.lang3.StringUtils;
public class ZipUtil {
/**
* 遞歸壓縮文件夾
*
* @param srcRootDir
* 壓縮文件夾根目錄的子路徑
* @param file
* 當前遞歸壓縮的文件或目錄對象
* @param zos
* 壓縮文件存儲對象
* @throws Exception
*/
private static void zip(String srcRootDir, File file, ZipOutputStream zos) throws Exception {
if (file == null) {
return;
}
// 如果是文件,則直接壓縮該文件
if (file.isFile()) {
int count, bufferLen = 1024;
byte data[] = new byte[bufferLen];
// 獲取文件相對於壓縮文件夾根目錄的子路徑
String subPath = file.getAbsolutePath();
int index = subPath.indexOf(srcRootDir);
if (index != -1) {
subPath = subPath.substring(srcRootDir.length() + File.separator.length());
}
ZipEntry entry = new ZipEntry(subPath);
zos.putNextEntry(entry);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
while ((count = bis.read(data, 0, bufferLen)) != -1) {
zos.write(data, 0, count);
}
bis.close();
zos.closeEntry();
}
// 如果是目錄,則壓縮整個目錄
else {
// 壓縮目錄中的文件或子目錄
File[] childFileList = file.listFiles();
for (int n = 0; n < childFileList.length; n++) {
childFileList[n].getAbsolutePath().indexOf(file.getAbsolutePath());
zip(srcRootDir, childFileList[n], zos);
}
}
}
/**
* 對文件或文件目錄進行壓縮
*
* @param srcPath
* 要壓縮的源文件路徑。如果壓縮一個文件,則為該文件的全路徑;如果壓縮一個目錄,則為該目錄的頂層目錄路徑
* @param zipPath
* 壓縮文件保存的路徑。注意:zipPath不能是srcPath路徑下的子文件夾
* @param zipFileName
* 壓縮文件名
* @throws Exception
*/
public static void zip(String srcPath, String zipPath, String zipFileName) throws Exception {
CheckedOutputStream cos = null;
ZipOutputStream zos = null;
try {
File srcFile = new File(srcPath);
// 判斷壓縮文件保存的路徑是否為源文件路徑的子文件夾,如果是,則拋出異常(防止無限遞歸壓縮的發生)
if (srcFile.isDirectory() && zipPath.indexOf(srcPath) != -1) {
throw new Exception("壓縮文件保存的路徑是否為源文件路徑的子文件夾");
}
// 判斷壓縮文件保存的路徑是否存在,如果不存在,則創建目錄
File zipDir = new File(zipPath);
if (!zipDir.exists() || !zipDir.isDirectory()) {
zipDir.mkdirs();
}
// 創建壓縮文件保存的文件對象
String zipFilePath = zipPath + File.separator + zipFileName;
File zipFile = new File(zipFilePath);
cos = new CheckedOutputStream(new FileOutputStream(zipFile), new CRC32());
zos = new ZipOutputStream(cos);
// 如果只是壓縮一個文件,則需要截取該文件的父目錄
String srcRootDir = srcPath;
if (srcFile.isFile()) {
int index = srcPath.lastIndexOf(File.separator);
if (index != -1) {
srcRootDir = srcPath.substring(0, index);
}
}
// 調用遞歸壓縮方法進行目錄或文件壓縮
zip(srcRootDir, srcFile, zos);
zos.flush();
} catch (Exception e) {
throw e;
} finally {
try {
if (zos != null) {
zos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 解壓縮zip包
*
* @param zipFilePath
* zip文件的全路徑
* @param unzipFilePath
* 解壓后的文件保存的路徑
* @param includeZipFileName
* 解壓后的文件保存的路徑是否包含壓縮文件的文件名。true-包含;false-不包含
*/
@SuppressWarnings({ "unchecked", "resource" })
public static void unzip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception {
File zipFile = new File(zipFilePath);
// 如果解壓后的文件保存路徑包含壓縮文件的文件名,則追加該文件名到解壓路徑
if (includeZipFileName) {
String fileName = zipFile.getName();
if (StringUtils.isNotEmpty(fileName)) {
fileName = fileName.substring(0, fileName.lastIndexOf("."));
}
unzipFilePath = unzipFilePath + File.separator + fileName;
}
// 創建解壓縮文件保存的路徑
File unzipFileDir = new File(unzipFilePath);
if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
unzipFileDir.mkdirs();
}
// 開始解壓
ZipEntry entry = null;
String entryFilePath = null, entryDirPath = null;
File entryFile = null, entryDir = null;
int index = 0, count = 0, bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
ZipFile zip = new ZipFile(zipFile);
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
// 循環對壓縮包里的每一個文件進行解壓
while (entries.hasMoreElements()) {
entry = entries.nextElement();
// 構建壓縮包中一個文件解壓后保存的文件全路徑
entryFilePath = unzipFilePath + File.separator + entry.getName();
// 構建解壓后保存的文件夾路徑
index = entryFilePath.lastIndexOf(File.separator);
if (index != -1) {
entryDirPath = entryFilePath.substring(0, index);
} else {
entryDirPath = "";
}
entryDir = new File(entryDirPath);
// 如果文件夾路徑不存在,則創建文件夾
if (!entryDir.exists() || !entryDir.isDirectory()) {
entryDir.mkdirs();
}
// 創建解壓文件
entryFile = new File(entryFilePath);
// 寫入文件
bos = new BufferedOutputStream(new FileOutputStream(entryFile));
bis = new BufferedInputStream(zip.getInputStream(entry));
while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
bos.write(buffer, 0, count);
}
bos.flush();
bos.close();
}
}
public static void main(String[] args) {
String usersHome = System.getProperty("user.home");
// 壓縮后文件存儲路徑
String targetZipPath = usersHome + "/testzip";
// 壓縮源文件(如果是文件, 則為全路徑 /groovy.png)
String sourcePath = usersHome + "/Documents/bakpic/testzip";
// 壓縮后文件名
String zipFileName = "hehe.zip";
try {
zip(sourcePath, targetZipPath, zipFileName);
} catch (Exception e) {
e.printStackTrace();
}
// 解壓源文件路徑
String zipFilePath = usersHome + "/testzip/hehe.zip";
// 解壓后文件存儲路徑
String unzipFilePath = usersHome + "/testzip/haha";
try {
unzip(zipFilePath, unzipFilePath, false);
} catch (Exception e) {
e.printStackTrace();
}
}
}