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

Java 建立 ZIP 壓縮檔:ZipOutputStream 完整實作範例

     編輯:Java 相關知識

核心類別

  • ZipOutputStream:寫入 ZIP 格式資料流
  • ZipEntry:代表壓縮檔內單一項目(檔案/目錄)
  • FileInputStream:讀取來源檔案

完整可執行程式


import java.io.*;
import java.util.zip.*;

public class ZipCreator {
    public static void main(String[] args) throws IOException {
        if (args.length == 0) {
            System.err.println("用法: java ZipCreator <檔案1> [檔案2] ...");
            return;
        }

        byte[] buffer = new byte[512];
        // 輸出至標準輸出,實際應用可改為 new FileOutputStream("output.zip")
        ZipOutputStream zout = new ZipOutputStream(System.out);

        for (String filePath : args) {
            FileInputStream in = new FileInputStream(filePath);
            // ZipEntry 名稱使用正斜線分隔,跨平台相容
            ZipEntry entry = new ZipEntry(filePath.replace(File.separatorChar, '/'));
            zout.putNextEntry(entry);

            int len;
            while ((len = in.read(buffer)) != -1) {
                zout.write(buffer, 0, len);
            }
            zout.closeEntry();
            in.close();
            printEntryInfo(entry);
        }
        zout.close();
    }

    private static void printEntryInfo(ZipEntry e) {
        PrintStream err = System.err;
        err.print("added " + e.getName());
        if (e.getMethod() == ZipEntry.DEFLATED) {
            long size = e.getSize();
            if (size > 0) {
                long csize = e.getCompressedSize();
                long ratio = ((size - csize) * 100) / size;
                err.println(" (deflated " + ratio + "%)");
            } else {
                err.println(" (deflated 0%)");
            }
        } else {
            err.println(" (stored 0%)");
        }
    }
}

關鍵實作細節

1. 緩衝區大小

512 bytes 為示範用較小值,實際建議 4096 或 8192(8KB)提升 I/O 效能。

2. 路徑分隔符標準化


new ZipEntry(filePath.replace(File.separatorChar, '/'))

ZIP 規範要求使用正斜線 / 作為路徑分隔,Windows 反斜線需轉換,確保跨平台解壓相容。

3. 壓縮方法與比率統計

  • DEFLATED:標準壓縮(預設)
  • STORED:僅存儲不壓縮
  • 壓縮比 = (原大小 - 壓縮後大小) * 100 / 原大小

4. 目錄項目處理

若需包含目錄結構,需顯式建立以 / 結尾的 ZipEntry:


ZipEntry dirEntry = new ZipEntry("mydir/");
zout.putNextEntry(dirEntry);
zout.closeEntry(); // 目錄項目無資料內容

進階擴展:遞歸壓縮整個目錄


public static void zipDirectory(File dir, ZipOutputStream zout, String basePath) throws IOException {
    File[] files = dir.listFiles();
    if (files == null) return;

    for (File file : files) {
        String entryName = basePath + file.getName();
        if (file.isDirectory()) {
            zipDirectory(file, zout, entryName + "/");
        } else {
            ZipEntry entry = new ZipEntry(entryName);
            zout.putNextEntry(entry);
            try (FileInputStream in = new FileInputStream(file)) {
                byte[] buf = new byte[8192];
                int len;
                while ((len = in.read(buf)) != -1) {
                    zout.write(buf, 0, len);
                }
            }
            zout.closeEntry();
        }
    }
}

Java 7+ try-with-resources 寫法


try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream("out.zip"));
     FileInputStream in = new FileInputStream(file)) {
    zout.putNextEntry(new ZipEntry(entryName));
    byte[] buf = new byte[8192];
    int len;
    while ((len = in.read(buf)) != -1) {
        zout.write(buf, 0, len);
    }
    zout.closeEntry();
} // 自動關閉 zout、in

常見問題與解決

問題原因解決
中文檔名解壓亂碼ZIP 標準未規定編碼,各工具預設不同使用 Apache Commons Compress 指定 UTF-8,或 JDK 7+ ZipFile(Charset)
大檔案記憶體不足一次讀入整個檔案分塊流式讀寫(如上範例)
空目錄不見ZipEntry 僅含檔案顯式建立目錄 Entry
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved