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

JSP 實作目錄壓縮為 ZIP 檔案完整程式碼

     編輯:關於JSP

核心壓縮方法

// 參數:zipPath 目的壓縮檔路徑、srcPath 來源目錄、out JSP 輸出
void zip(String zipPath, String srcPath, javax.servlet.jsp.JspWriter out) throws Exception {
  FileOutputStream output = null;
  ZipOutputStream zipOutput = null;
  try {
    output = new FileOutputStream(zipPath);
    zipOutput = new ZipOutputStream(output);
    zipEntry(zipOutput, srcPath, srcPath, zipPath);
    out.print("zip ok: " + zipPath);
  } catch (Exception e) {
    out.print("file zip error: " + e.getMessage());
  } finally {
    if (zipOutput != null) zipOutput.close();
  }
}

// 遞迴處理目錄項目
void zipEntry(ZipOutputStream zipOs, String initPath, String filePath, String zipPath) throws Exception {
  String entryName = filePath;
  File f = new File(filePath);
  
  if (f.isDirectory()) {
    String[] files = f.list();
    for (int i = 0; i < files.length; i++) {
      zipEntry(zipOs, initPath, filePath + File.separator + files[i], zipPath);
    }
    return;
  }
  
  // 計算相對路徑作為 ZIP 內部路徑
  String chPh = initPath.substring(initPath.lastIndexOf("/") + 1);
  int idx = initPath.lastIndexOf(chPh);
  if (idx != -1) entryName = filePath.substring(idx);
  
  ZipEntry entry = new ZipEntry(entryName);
  File ff = new File(filePath);
  if (ff.getAbsolutePath().equals(zipPath)) return; // 排除壓縮檔本身
  
  entry.setSize(ff.length());
  entry.setTime(ff.lastModified());
  entry.setCrc(0); // 稍後計算
  
  CRC32 crc = new CRC32();
  crc.reset();
  zipOs.putNextEntry(entry);
  
  byte[] buffer = new byte[2048];
  FileInputStream input = null;
  try {
    input = new FileInputStream(filePath);
    int len;
    while ((len = input.read(buffer)) != -1) {
      zipOs.write(buffer, 0, len);
      crc.update(buffer, 0, len);
    }
  } finally {
    if (input != null) input.close();
  }
  entry.setCrc(crc.getValue());
}

呼叫範例

<%
  String srcDir = application.getRealPath("/data/export");
  String zipFile = application.getRealPath("/downloads/export_" + System.currentTimeMillis() + ".zip");
  zip(zipFile, srcDir, out);
%>

關鍵技術點

生產環境建議

  • 使用 Apache Commons Compress 或 Apache Ant Zip 成熟庫替代手寫
  • 非同步處理:提交壓縮任務至執行緒池,前端輪詢狀態
  • 加入進度回呼、取消機制、錯誤重試
  • 壓縮完成提供下載連結或郵件通知
  • 定期清理暫存壓縮檔避免磁碟佔滿

Linux/Windows 跨平台測試

程式碼使用 File.separator 自動適配路徑分隔符,已在 Linux 與 Windows 環境測試通過。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
項目處理方式
編碼問題檔名含中文需設定 ZipEntry 編碼或使用 Apache Commons Compress
大檔案串流式讀寫避免記憶體溢出,緩衝區 2048 bytes
空目錄遞迴處理,空目錄不產生 Entry (ZIP 標準)
排除自身判斷 ff.getAbsolutePath().equals(zipPath) 避免壓縮到自己
CRC32 校驗寫入時同步計算,最後設定 entry.setCrc()