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

Java 產生 ZIP 壓縮檔並輸出至 HttpServletResponse 導致檔案損壞的根因與修正

     編輯:程式設計綜合問答

常見錯誤程式碼

ZipOutputStream zos = new ZipOutputStream(baos);
zos.putNextEntry(new ZipEntry("goods.txt"));
zos.write(bytes);
zos.flush();
zos.closeEntry();
baos.close(); // 過早關閉 ByteArrayOutputStream
zos.close();
os.write(baos.toByteArray()); // baos 已關閉,資料可能不完整

根本原因

  1. 關閉順序錯誤:先關閉 baos 再 toByteArray() 會導致資料截斷。
  2. 未正確 flush/close ZipOutputStream:ZIP 中央目錄未寫入,導致解壓軟體判定損壞。
  3. Response 處理順序:應先設定 Header 再寫入資料流。

修正後的標準流程

response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=goods.zip");
response.setHeader("Content-Length", String.valueOf(baos.size())); // 可選

try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
     ZipOutputStream zos = new ZipOutputStream(baos);
     ServletOutputStream os = response.getOutputStream()) {

    zos.putNextEntry(new ZipEntry("goods.txt"));
    zos.write(bytes);
    zos.closeEntry();
    zos.finish(); // 關鍵:寫入中央目錄

    byte[] data = baos.toByteArray();
    response.setContentLength(data.length);
    os.write(data);
    os.flush();
}

關鍵點總結

  • zos.finish() 必須在 baos.toByteArray() **之前**呼叫。
  • 使用 try-with-resources 確保資源正確關閉。
  • 大檔案建議直接串流寫入 response.getOutputStream(),避免記憶體暴增。

參考資源

百度經驗:Java 生成 ZIP 下載完整範例

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved