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

Java 使用 Apache Ant Zip 實現檔案/目錄遞歸壓縮工具類

     編輯:Java 相關知識

基於 org.apache.tools.zip 的壓縮工具完整實作

標準 JDK java.util.zip 對中文檔名支援較差,採用 Apache Ant 的 org.apache.tools.zip 可完美解決編碼問題,並支援 ZipEntry 目錄項目。

Maven 依賴

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant</artifactId>
    <version>1.10.14</version>
</dependency>

核心工具類 CompressedFileUtil

import java.io.*;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

public class CompressedFileUtil {

    /** 預設建構子 */
    public CompressedFileUtil() {}

    /**
     * 壓縮指定檔案或目錄為 ZIP
     * @param resourcesPath 來源路徑(檔案或資料夾)
     * @param targetPath 目標壓縮檔存放目錄
     * @throws Exception
     */
    public void compressedFile(String resourcesPath, String targetPath) throws Exception {
        File resourcesFile = new File(resourcesPath);
        File targetDir = new File(targetPath);
        
        if (!targetDir.exists()) targetDir.mkdirs();
        
        String zipName = resourcesFile.getName() + ".zip";
        FileOutputStream fos = new FileOutputStream(new File(targetDir, zipName));
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
        
        createCompressedFile(zos, resourcesFile, "");
        zos.close();
    }

    /**
     * 遞歸建立壓縮項目
     */
    private void createCompressedFile(ZipOutputStream out, File file, String dir) throws Exception {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            // 加入目錄項目(以 / 結尾)
            out.putNextEntry(new ZipEntry(dir + "/"));
            dir = dir.isEmpty() ? "" : dir + "/";
            
            for (File f : files) {
                createCompressedFile(out, f, dir + f.getName());
            }
        } else {
            // 檔案項目
            FileInputStream fis = new FileInputStream(file);
            out.putNextEntry(new ZipEntry(dir));
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            fis.close();
        }
    }

    /** 測試主程式 */
    public static void main(String[] args) {
        CompressedFileUtil util = new CompressedFileUtil();
        try {
            util.compressedFile("G:\\zip", "F:\\zip");
            System.out.println("壓縮檔案已生成...");
        } catch (Exception e) {
            System.out.println("壓縮失敗...");
            e.printStackTrace();
        }
    }
}

關鍵設計細節

  1. 目錄項目處理:ZipEntry(name + "/") 明確標示目錄,解壓時可正確建立資料夾結構。
  2. 相對路徑構建:遞歸參數 dir 累加相對路徑,確保壓縮包內層級正確。
  3. 緩衝流優化:使用 BufferedOutputStream 包裝 FileOutputStream,再包裝 ZipOutputStream,提升寫入效能。
  4. 資源釋放:finally 區塊或 try-with-resources 確保流關閉(JDK 7+ 建議改用 try-with-resources)。

進階擴展建議

  • 支援多執行緒並行壓縮大量小檔案
  • 加入壓縮等級設定 zos.setLevel(Deflater.BEST_COMPRESSION)
  • 實作進度回呼介面供 UI 顯示進度條
  • 支援 ZIP64 格式處理超過 4GB 的大檔案

常見問題排查

問題原因解決
中文檔名解壓亂碼JDK 預設 ZIP 使用 UTF-8,Windows 預設 GBK使用 Apache Ant Zip 並設定 encoding:zos.setEncoding("GBK") 或 UTF-8
空目錄未壓縮listFiles() 回傳 null 或空陣列目錄項目已在遞歸入口建立,空目錄會生成對應 Entry
大檔案記憶體溢位一次性讀入整個檔案採用 1KB~8KB 緩衝區分塊讀寫(本範例已採用)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved