完整可用原始碼
import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class UnZipper {
/**
* 解壓 ZIP 檔案至其所在目錄(相當於右鍵「解壓到當前資料夾」)
*
* @param zipFile 待解壓的 ZIP 檔案物件
* @throws IOException I/O 異常
*/
@SuppressWarnings("rawtypes")
public static void unZipFiles(File zipFile) throws IOException {
// 取得 ZIP 檔所在目錄
String baseDir = zipFile.getAbsolutePath();
baseDir = baseDir.substring(0, baseDir.lastIndexOf(File.separator));
try (ZipFile zip = new ZipFile(zipFile)) {
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
String entryName = entry.getName();
// 組合輸出完整路徑,統一使用正斜線再轉為系統分隔符
String outPath = (baseDir + File.separator + entryName).replace('/', File.separatorChar);
// 若為目錄項,建立目錄並跳過
if (entry.isDirectory()) {
new File(outPath).mkdirs();
continue;
}
// 確保父目錄存在
File parentDir = new File(outPath).getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
// 串流複製
try (InputStream in = zip.getInputStream(entry);
OutputStream out = new FileOutputStream(outPath)) {
byte[] buffer = new byte[4096];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
System.out.println("已解壓: " + outPath);
}
System.out.println("****************** 解壓完畢 ********************");
}
}
// 測試主程式
public static void main(String[] args) {
try {
// 請替換為實際 ZIP 路徑
unZipFiles(new File("D:/data/archive.zip"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
關鍵設計細節
| 細節 | 處理方式 |
| 跨平台路徑分隔符 | 使用 File.separator 而非硬編碼 \\ 或 / |
| 目錄項處理 | 利用 ZipEntry.isDirectory() 判斷,僅 mkdirs() 不開啟輸出流 |
| 資源自動關閉 | 採用 try-with-resources(Java 7+),確保 ZipFile、輸入/輸出流一定關閉 |
| 緩衝區大小 | 4096 bytes(4KB),平衡記憶體與 I/O 效能 |
| 中文檔名編碼 | JDK 7+ ZipFile 預設使用 UTF-8;若遇舊版 ZIP (GBK),需自行指定 new ZipFile(zipFile, StandardCharsets.ISO_8859_1) 並手動轉碼 |
常見擴充需求
- 指定解壓目標目錄:方法簽名改為
unZipFiles(File zipFile, File destDir),baseDir 改用 destDir.getAbsolutePath()。
- 解壓進度回調:引入
Consumer<ProgressInfo> 參數,於迴圈中回報 entryName、已處理位元組數、總大小。
- 覆蓋策略:檔案存在時可選
SKIP/OVERWRITE/RENAME。
- 支援更多格式:整合 Apache Commons Compress 處理
.tar.gz、.7z、.rar 等。
效能提示
- 大量小檔案時,
ZipFile 隨機存取優於 ZipInputStream 串流讀取。
- 若需極致速度,可考慮平行化處理獨立 Entry(注意磁碟 I/O 爭用)。
- 記憶體受限環境可減小緩衝區至 1024 bytes。