首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java GZIP 壓縮與解壓縮工具類:支援檔案、位元組陣列與流的完整實現

     編輯:Java 程式設計入門

前言

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;
}

核心實現細節

1. 位元組陣列壓縮/解壓

以 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();
    }
}

2. 流層面的通用壓縮邏輯

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)
    }
}

3. 檔案操作統一委派給流方法

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();
}

4. 解壓縮對稱實現

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);

關鍵技術點提示

  • finish() vs close():GZIPOutputStream 必須呼叫 finish() 寫入尾部 CRC32 與原始大小(ISIZE),close() 會自動呼叫 finish() 並關閉下游流。使用 try-with-resources 時由 close() 保證。
  • 緩衝區大小:1024 位元組屬保守設定,大檔案建議 8192 或 65536 以提升吞吐。
  • 大檔案記憶體:byte[] compress(byte[]) 會將整個壓縮結果載入記憶體,超過百 MB 檔案請改用流式檔案處理。
  • 多重壓縮:GZIP 不支援多檔案封裝(如 ZIP),若需打包目錄請改用 ZipOutputStream 或 Apache Commons Compress。
  • 編碼問題:GZIP 僅處理位元組,文字檔壓縮前請確認字元編碼(建議 UTF-8)。

擴充建議

  1. 新增 compress(Path, Path, boolean) 支援 NIO.2 Path API。
  2. 提供 CompressionLevel 參數(Deflater.BEST_SPEED ~ BEST_COMPRESSION)。
  3. 整合 CRC32 校驗值回傳,供完整性驗證。
  4. 支援 GZIPInputStream 的 syncFlush() 實現流式邊界控制。

總結

GZipUtils 以 流為核心抽象,通過方法重載覆蓋檔案、位元組陣列、路徑字串三種常見場景,程式碼無冗餘、異常透傳、資源自動釋放,是專案中處理 GZIP 壓縮的可靠基礎組件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved