首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java Zip 壓縮工具類解析:base 參數遞歸構建壓縮包內部路徑

     編輯:程式設計疑難解答

代碼片段


private void zip(String zipFileName, File inputFile) throws Exception {
    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
    zip(out, inputFile, ""); // 第三個參數傳空字符串
    out.close();
}

private void zip(ZipOutputStream out, File f, String base) throws Exception {
    if (f.isDirectory()) {
        File[] fl = f.listFiles();
        out.putNextEntry(new ZipEntry(base + "/")); // 目錄條目以 / 結尾
        base = base.length() == 0 ? "" : base + "/"; // 三目運算符處理路徑拼接
        for (int i = 0; i < fl.length; i++) {
            zip(out, fl[i], base + fl[i].getName()); // 遞歸:父路徑 + 文件名
        }
    } else {
        out.putNextEntry(new ZipEntry(base)); // 文件條目
        // ... 寫入文件內容
    }
}

參數含義解析

base 參數演示:壓縮 src 目錄


文件結構:
src/
├── Main.java
└── com/
    └── example/
        └── Util.java

調用: zip(out, new File("src"), "")

遞歸過程:
1. zip(src, base="")
   - 是目錄 → putNextEntry("") → base = ""
   - 遍歷 children:
     2. zip(Main.java, base="" + "Main.java" = "Main.java")
        - 是文件 → putNextEntry("Main.java")
     3. zip(com, base="" + "com" = "com")
        - 是目錄 → putNextEntry("com/") → base = "com/"
        - 遍歷 children:
          4. zip(example, base="com/" + "example" = "com/example")
             - 是目錄 → putNextEntry("com/example/") → base = "com/example/"
             - 遍歷 children:
               5. zip(Util.java, base="com/example/" + "Util.java" = "com/example/Util.java")
                  - 是文件 → putNextEntry("com/example/Util.java")

壓縮包內結構:
Main.java
com/
└── example/
    └── Util.java

關鍵代碼行解讀


// 三目運算符:如果 base 為空串,保持空串;否則加 "/"
base = base.length() == 0 ? "" : base + "/";

// 等價於:
if (base.isEmpty()) {
    base = "";
} else {
    base = base + "/";
}

// 作用:確保目錄條目以 "/" 結尾,文件條目不以 "/" 開頭
// 避免出現 "//Main.java" 或 "com//example" 這種雙斜杠

完整可運行工具類


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

public class ZipUtil {
    
    public static void zip(String zipFilePath, String sourcePath) throws IOException {
        File sourceFile = new File(sourcePath);
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            zip(zos, sourceFile, "");
        }
    }
    
    private static void zip(ZipOutputStream zos, File file, String base) throws IOException {
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                // 目錄條目
                if (!base.isEmpty()) {
                    zos.putNextEntry(new ZipEntry(base + "/"));
                }
                String newBase = base.isEmpty() ? "" : base + "/";
                for (File child : children) {
                    zip(zos, child, newBase + child.getName());
                }
            }
        } else {
            // 文件條目
            zos.putNextEntry(new ZipEntry(base));
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
            }
            zos.closeEntry();
        }
    }
    
    public static void main(String[] args) throws IOException {
        ZipUtil.zip("hello.zip", "src");
        System.out.println("壓縮完成");
    }
}

總結

  • base = "":初始調用傳空串,表示壓縮包根目錄
  • base 作用:記錄**壓縮包內部相對路徑**,遞歸時逐層拼接
  • 三目運算符:處理路徑分隔符拼接,避免首個路徑以 / 開頭或出現雙斜杠
  • ZipEntry 規則:目錄以 / 結尾,文件不以 / 開頭
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數含義初始值遞歸變化
zipFileName輸出壓縮包路徑"hello.zip"不變
inputFile待壓縮文件/目錄new File("src")遞歸遍歷子文件
base壓縮包內相對路徑前綴"" (空字符串)逐層拼接:base + "/" + filename