資料來源常含冗餘資訊,導致儲存空間浪費與傳輸頻寬壓力。雖然增加硬體設備可緩解,但成本高昂。更有效的方案是透過演算法以更緊湊編碼表示資料。本文介紹資料壓縮原理、java.util.zip 套件用法、序列化物件壓縮、以及客戶端/伺服器應用中的效能優化實作。
最簡單的壓縮形式,針對連續重複字元。例如字串 BBBBHHDDXXXXKKKKWWZZZZ 可編碼為 4B2H2D4X4K2W4Z,其中 4B 代表 4 個 B。此法適用於重複度高的資料(如單色位圖)。
0,40 表示 40 個白點)矩形 11,3,20,5),極度精簡
圖表 1:帶執行長度編碼資訊的位圖
詳細理論請參考資料與影像壓縮專業書籍。

圖形 2:資料壓縮方塊圖
| 特性 | ZIP (WinZip/PKZIP) | GZIP (gzip) |
|---|---|---|
| 功能定位 | 兼具封存與壓縮 | 僅壓縮,不封存 |
| Unix 慣用流程 | 單一工具完成 | tar 封存 → gzip 壓縮 |
| Java 支援 | java.util.zip 完整支援 | java.util.zip 完整支援 |
提供相容 ZIP/GZIP 格式的壓縮、解壓縮、校驗和計算功能。核心介面與類別如下:
| 類別/介面 | 類型 | 用途 |
|---|---|---|
| Checksum | 介面 | Adler32、CRC32 實作基礎 |
| Adler32 / CRC32 | 類別 | 計算資料流校驗和 |
| CheckedInputStream / OutputStream | 類別 | 讀寫時同步維護校驗和 |
| Deflater / Inflater | 類別 | ZLIB 庫通用壓縮/解壓縮引擎 |
| DeflaterOutputStream / InflaterInputStream | 類別 | 串流過濾器,處理壓縮格式 |
| GZIPInputStream / OutputStream | 類別 | GZIP 格式專用串流 |
| ZipEntry | 類別 | 代表 ZIP 檔案內單一條目 |
| ZipFile | 類別 | 隨機存取讀取 ZIP 檔條目 |
| ZipInputStream / OutputStream | 類別 | ZIP 格式串流讀寫 |
| DataFormatException / ZipException | 異常 | 資料格式錯誤 / ZIP 專用錯誤 |
註:ZLIB 庫原為 PNG 格式開發,不受專利限制。
// 壓縮
try (FileInputStream fis = new FileInputStream("data.txt");
FileOutputStream fos = new FileOutputStream("data.gz");
GZIPOutputStream gzos = new GZIPOutputStream(fos)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
gzos.write(buffer, 0, len);
}
}
// 解壓縮
try (GZIPInputStream gzis = new GZIPInputStream(new FileInputStream("data.gz"));
FileOutputStream fos = new FileOutputStream("data.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = gzis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
// 建立 ZIP
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("archive.zip"))) {
addToZip("file1.txt", zos);
addToZip("dir/file2.txt", zos);
}
void addToZip(String path, ZipOutputStream zos) throws IOException {
try (FileInputStream fis = new FileInputStream(path)) {
zos.putNextEntry(new ZipEntry(path));
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
}
}
// 寫入壓縮序列化物件
try (ObjectOutputStream oos = new ObjectOutputStream(
new GZIPOutputStream(new FileOutputStream("obj.gz")))) {
oos.writeObject(mySerializableObject);
}
// 讀取解壓縮還原
try (ObjectInputStream ois = new ObjectInputStream(
new GZIPInputStream(new FileInputStream("obj.gz")))) {
MyObject obj = (MyObject) ois.readObject();
}
在網路傳輸前壓縮資料,可大幅降低頻寬占用與延遲:
// Client 發送壓縮資料
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
ObjectOutputStream oos = new ObjectOutputStream(gzos)) {
oos.writeObject(requestObject);
byte[] compressed = baos.toByteArray();
socket.getOutputStream().write(compressed);
}
// Server 接收解壓縮
try (InputStream is = socket.getInputStream();
GZIPInputStream gzis = new GZIPInputStream(is);
ObjectInputStream ois = new ObjectInputStream(gzis)) {
RequestObject req = (RequestObject) ois.readObject();
}
java.util.zip 提供標準、高效的壓縮解決方案,無需外部工具即可在應用程式內部完成資料壓縮、解壓縮、校驗和計算。善用串流鏈結模式(GZIPOutputStream → ObjectOutputStream),可輕鬆實現物件序列化壓縮與網路傳輸優化,是 Java 開發者必備的工具箱技能。