Java解壓縮zip檔案工具類(支援zip資料夾下多級目錄結構)
阿新 • • 發佈:2018-11-20
文章目錄
Java解壓縮zip檔案工具類(支援zip資料夾下多級目錄結構)
1. 前言
由於工作需要一個能夠解壓縮zip的工具類,但查看了不少部落格,發現檢視的文章裡都只支援zip資料夾下的一級檔案結構,但實際生活中,zip資料夾下存在多級目錄及檔案是很隨意的事情,所以萌生了封裝這樣一個能夠解壓縮多級目錄結構檔案的想法。
2. 正文
2.1 解壓縮後文件目錄結構展示
2.2 注意事項
- 若zip檔案中包含中文的話,可能需要制定字元編碼,若不指定的話,預設使用
UTF8
字元編碼 - Windows系統壓縮編碼一般為
GBK
,GB2312
,UTF8
,Linux系統壓縮編碼一般為UTF8
- 測試資料使用
GB2312
能夠正常解碼,使用其它均不能正常解碼
2.3 異常
2.3.1 可能會遇到的異常
java.lang.IllegalArgumentException: MALFORMED
at java.util.zip.ZipCoder.toString(ZipCoder. java:58)
at java.util.zip.ZipFile.getZipEntry(ZipFile.java:583)
at java.util.zip.ZipFile.access$900(ZipFile.java:60)
at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:539)
at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:514)
at java.util.zip.ZipFile$ZipEntryIterator.nextElement (ZipFile.java:495)
at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:91)
at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:54)
at com.tdt.sc.utils.FileUtils.unpack(FileUtils.java:34)
at com.tdt.sc.utils.FileUtils.main(FileUtils.java:23)
2.3.2 解決方案
- 此異常為字元編碼解碼異常
- 建議使用其它字元編碼進行解碼,具體參見 注意事項
2.4 具體程式碼實現
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @program:
* @description: 檔案解壓縮工具類
* @author: Mr.superbeyone
* @create: 2018-10-23 14:04
**/
public class FileUtils {
/**
* 此方法將預設設定解壓縮後文件的儲存路徑為zip檔案所在路徑
* 即解壓縮到當前資料夾下
* @param zip zip檔案位置
* @param charsetName 字元編碼
*/
public static void unpack(String zip, String charsetName) {
unpack(new File(zip), charsetName);
}
/**
*
* @param zip zip檔案位置
* @param outputDir 解壓縮後文件儲存路徑
* @param charsetName 字元編碼
*/
public static void unpack(String zip, String outputDir, String charsetName) {
unpack(new File(zip), new File(outputDir), charsetName);
}
/**
* 此方法將預設設定解壓縮後文件的儲存路徑為zip檔案所在路徑
* 即解壓縮到當前資料夾
* @param zip zip檔案位置
* @param charsetName 字元編碼
*/
public static void unpack(File zip, String charsetName) {
unpack(zip, null, charsetName);
}
/**
*
* @param zip zip檔案位置
* @param outputDir 解壓縮後文件儲存路徑
*/
public static void unpack(File zip, File outputDir) {
unpack(zip, outputDir, "");
}
/**
*
* @param zip zip檔案位置
* @param outputDir 解壓縮後文件儲存路徑
* @param charsetName 字元編碼
*/
public static void unpack(File zip, File outputDir, String charsetName) {
FileOutputStream out = null;
InputStream in = null;
//讀出檔案資料
ZipFile zipFileData = null;
ZipFile zipFile = null;
try {
//若目標儲存檔案位置不存在
if (outputDir != null) if (!outputDir.exists()) {
outputDir.mkdirs();
}
if (charsetName != null && charsetName != "") {
zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
} else {
zipFile = new ZipFile(zip.getPath(), Charset.forName("utf8"));
}
//zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
Enumeration<? extends ZipEntry> entries = zipFile.entries();
//處理建立資料夾
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String filePath = "";
if (outputDir == null) {
filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
} else {
filePath = outputDir.getPath() + File.separator + entry.getName();
}
File file = new File(filePath);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
if (parentFile.isDirectory()) {
continue;
}
}
if (charsetName != null && charsetName != "") {
zipFileData = new ZipFile(zip.getPath(), Charset.forName(charsetName));
} else {
zipFileData = new ZipFile(zip.getPath(), Charset.forName("utf8"));
}
Enumeration<? extends ZipEntry> entriesData = zipFileData.entries();
while (entriesData.hasMoreElements()) {
ZipEntry entry = entriesData.nextElement();
in = zipFile.getInputStream(entry);
String filePath = "";
if (outputDir == null) {
filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
} else {
filePath = outputDir.getPath() + File.separator + entry.getName();
}
File file = new File(filePath);
if (file.isDirectory()) {
continue;
}
out = new FileOutputStream(filePath);
int len = -1;
byte[] bytes = new byte[1024];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
zipFile.close();
zipFileData.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.4 遺留問題
以下問題未做處理:
- 壓縮檔案內可能包含其它壓縮檔案
- 壓縮檔案內若存在空資料夾,則該資料夾會被當成檔案處理,即生成以該資料夾名命名的空檔案