java.util.zip.GZIPInputStream 與 GZIPOutputStream 是 Java 標準庫提供的 GZIP 壓縮/解壓流實現。本文封裝一個 GZipUtils 工具類,統一處理檔案、位元組陣列、輸入/輸出流三種資料源,並提供是否刪除原檔選項,適合直接整合到專案中作為基礎組件。
public abstract class GZipUtils {
public static final int BUFFER = 1024;
public static final String EXT = ".gz";
// 壓縮系列
public static byte[] compress(byte[] data) throws Exception;
public static void compress(File file) throws Exception;
public static void compress(File file, boolean delete) throws Exception;
public static void compress(InputStream is, OutputStream os) throws Exception;
public static void compress(String path) throws Exception;
public static void compress(String path, boolean delete) throws Exception;
// 解壓縮系列
public static byte[] decompress(byte[] data) throws Exception;
public static void decompress(File file) throws Exception;
public static void decompress(File file, boolean delete) throws Exception;
public static void decompress(InputStream is, OutputStream os) throws Exception;
public static void decompress(String path) throws Exception;
public static void decompress(String path, boolean delete) throws Exception;
}
以 ByteArrayInputStream/ByteArrayOutputStream 為橋接,複用流處理邏輯:
public static byte[] compress(byte[] data) throws Exception {
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
compress(bais, baos);
return baos.toByteArray();
}
}
public static void compress(InputStream is, OutputStream os) throws Exception {
try (GZIPOutputStream gos = new GZIPOutputStream(os)) {
byte[] buffer = new byte[BUFFER];
int count;
while ((count = is.read(buffer, 0, BUFFER)) != -1) {
gos.write(buffer, 0, count);
}
gos.finish(); // 關鍵:寫入 GZIP 尾部資訊(CRC32、ISIZE)
}
}
public static void compress(File file, boolean delete) throws Exception {
try (FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file.getPath() + EXT)) {
compress(fis, fos);
}
if (delete) file.delete();
}
public static void decompress(InputStream is, OutputStream os) throws Exception {
try (GZIPInputStream gis = new GZIPInputStream(is)) {
byte[] buffer = new byte[BUFFER];
int count;
while ((count = gis.read(buffer, 0, BUFFER)) != -1) {
os.write(buffer, 0, count);
}
// GZIPInputStream 讀取至 EOF 會自動校驗 CRC32
}
}
// 1. 檔案壓縮(保留原檔)
GZipUtils.compress(new File("data.log"), false);
// 2. 檔案解壓縮(刪除 .gz)
GZipUtils.decompress(new File("data.log.gz"), true);
// 3. 位元組陣列壓縮(常用於網路傳輸前)
byte[] compressed = GZipUtils.compress(jsonString.getBytes(StandardCharsets.UTF_8));
// 4. 位元組陣列解壓縮
byte[] original = GZipUtils.decompress(compressed);
GZIPOutputStream 必須呼叫 finish() 寫入尾部 CRC32 與原始大小(ISIZE),close() 會自動呼叫 finish() 並關閉下游流。使用 try-with-resources 時由 close() 保證。byte[] compress(byte[]) 會將整個壓縮結果載入記憶體,超過百 MB 檔案請改用流式檔案處理。ZipOutputStream 或 Apache Commons Compress。compress(Path, Path, boolean) 支援 NIO.2 Path API。CompressionLevel 參數(Deflater.BEST_SPEED ~ BEST_COMPRESSION)。CRC32 校驗值回傳,供完整性驗證。GZIPInputStream 的 syncFlush() 實現流式邊界控制。GZipUtils 以 流為核心抽象,通過方法重載覆蓋檔案、位元組陣列、路徑字串三種常見場景,程式碼無冗餘、異常透傳、資源自動釋放,是專案中處理 GZIP 壓縮的可靠基礎組件。