溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java如何實(shí)現(xiàn)多文件壓縮下載

發(fā)布時(shí)間:2021-09-26 10:31:55 來源:億速云 閱讀:164 作者:小新 欄目:編程語言

這篇文章主要為大家展示了“java如何實(shí)現(xiàn)多文件壓縮下載”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“java如何實(shí)現(xiàn)多文件壓縮下載”這篇文章吧。

需求:

會(huì)員運(yùn)營平臺(tái)經(jīng)過改版后頁面增加了許多全部下載鏈接,上周上線比較倉促,全部下載是一個(gè)直接下載ZIP壓縮文件的鏈接,每個(gè)ZIP壓縮文件都是由公司運(yùn)營人員將頁面需要下載的文件全部壓縮成一個(gè)ZIP壓縮文件,然后通過公司的交易運(yùn)營平臺(tái)上傳至文件資料系統(tǒng),會(huì)員運(yùn)營平臺(tái)則可以直接獲取ZIP壓縮文件地址進(jìn)行下載

下面是一個(gè)頁面示例:

需求分析:

通過上面需求和頁面可以分析出,公司運(yùn)營人員將頁面全部需要下載的文件進(jìn)行ZIP壓縮后上傳文件資料系統(tǒng)確實(shí)是一個(gè)緊急的解決方案,但是考慮到后面需求變更,頁面需要下載的文件也會(huì)跟著變更,每次變更需求,公司運(yùn)營人員都需要重新進(jìn)行壓縮文件,程序也需要進(jìn)行相應(yīng)的修改,這樣對(duì)于程序的維護(hù)性不友好,站在使用系統(tǒng)的客戶角度,每次都需要重新上傳,因此臨時(shí)解決方案不再符合軟件的良好擴(kuò)展性和操作方便,因此才有了對(duì)頁面需要全部下載的文件使用程序壓縮處理并下載。

解決思路:

第一步:前端傳遞Ids字符串

由于會(huì)員運(yùn)營系統(tǒng)顯示需要下載的文件是資料系統(tǒng)中的每條文件記錄的Id,因此前端頁面只需要將需要下載的所有文件Ids字符串(比如:'12,13,14')傳遞到后臺(tái)即可.

第二步:后臺(tái)處理

首先獲取到前端傳遞的ids字符串,將其轉(zhuǎn)換為Integer[]的ids數(shù)組,然后調(diào)用文件資料微服務(wù)根據(jù)id列表查詢對(duì)應(yīng)的文件記錄(包含文件類型和文件地址路徑等信息),獲取到所有需要下載的文件路徑后壓縮成ZIP格式的文件進(jìn)行下載。

附上完整代碼:

壓縮下載Controller

package com.huajin.jgoms.controller.user; import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;import java.util.Objects;import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; import org.apache.commons.collections.CollectionUtils;import org.apache.commons.lang3.ObjectUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping; import com.huajin.baymax.logger.XMsgError;import com.huajin.baymax.logger.Xlogger;import com.huajin.common.util.UUIDUtil;import com.huajin.exchange.domain.sys.FeFileCenter;import com.huajin.exchange.enums.sys.SysParamKey;import com.huajin.exchange.po.sys.SysParamPo;import com.huajin.jgoms.controller.HjBaseController;import com.huajin.jgoms.service.FeFileCenterService;import com.huajin.jgoms.service.SysParamService;import com.huajin.jgoms.util.CompressDownloadUtil; /** * 壓縮下載文件 * * @author hongwei.lian * @date 2018年9月6日 下午6:29:05 */@Controller@RequestMapping("/compressdownload")public class CompressDownloadController extends HjBaseController {  @Autowired private FeFileCenterService feFileCenterService;  @Autowired private SysParamService sysParamService;  /** * 多文件壓縮下載 *  * @author hongwei.lian * @date 2018年9月6日 下午6:28:56 */ @RequestMapping("/downloadallfiles") public void downloadallfiles() { //-- 1、根據(jù)ids查詢下載的文件地址列表 String ids = request().getParameter("ids"); if (StringUtils.isEmpty(ids)) { return ; } //-- 將字符串?dāng)?shù)組改變?yōu)檎蛿?shù)組 Integer[] idsInteger = CompressDownloadUtil.toIntegerArray(ids); List<FeFileCenter> fileCenters = feFileCenterService.getFeFileByIds(super.getExchangeId(), idsInteger); if (CollectionUtils.isNotEmpty(fileCenters) && ObjectUtils.notEqual(idsInteger.length, fileCenters.size())) { //-- 要下載文件Id數(shù)組個(gè)數(shù)和返回的文件地址個(gè)數(shù)不一致 return ; }  //-- 2、轉(zhuǎn)換成文件列表 List<File> files = this.toFileList(fileCenters); //-- 檢查需要下載多文件列表中文件路徑是否都存在 for (File file : files) { if (!file.exists()) { //-- 需要下載的文件中存在不存在地址 return ; } }  //-- 3、響應(yīng)頭的設(shè)置 String downloadName = UUIDUtil.getUUID() + ".zip"; HttpServletResponse response = CompressDownloadUtil.setDownloadResponse(super.response(), downloadName);  //-- 4、第一種方案: //-- 指定ZIP壓縮包路徑// String zipFilePath = this.setZipFilePath(downloadName);// try {// //-- 將多個(gè)文件壓縮到指定路徑下// CompressDownloadUtil.compressZip(files, new FileOutputStream(zipFilePath));// //-- 下載壓縮包// CompressDownloadUtil.downloadFile(response.getOutputStream(), zipFilePath);// //-- 刪除臨時(shí)生成的ZIP文件// CompressDownloadUtil.deleteFile(zipFilePath);// } catch (IOException e) {// Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e));// }  //-- 5、第二種方案: try { //-- 將多個(gè)文件壓縮寫進(jìn)響應(yīng)的輸出流 CompressDownloadUtil.compressZip(files, response.getOutputStream()); } catch (IOException e) { Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e)); }  }  /** * 設(shè)置臨時(shí)生成的ZIP文件路徑 * * @param fileName * @return  * @author hongwei.lian * @date 2018年9月7日 下午3:54:13 */ private String setZipFilePath(String fileName) { String zipPath = sysParamService.getCompressDownloadFilePath(); File zipPathFile = new File(zipPath); if (!zipPathFile.exists()) { zipPathFile.mkdirs(); } return zipPath + File.separator + fileName; }  /** * 將fileCenters列表轉(zhuǎn)換為File列表 * * @param fileCenters * @return  * @author hongwei.lian * @date 2018年9月6日 下午6:54:16 */ private List<File> toFileList(List<FeFileCenter> fileCenters) { return fileCenters.stream()   .map(feFileCenter -> {   //-- 獲取每個(gè)文件的路徑   String filePath = this.getSysFilePath(feFileCenter.getFileTypeId());   return new File(filePath + feFileCenter.fileLink());})   .collect(Collectors.toList()); }  /** * 獲取文件類型對(duì)應(yīng)存儲(chǔ)路徑 * * @param fileTypeId * @return  * @author hongwei.lian * @date 2018年9月5日 下午2:01:53 */ private String getSysFilePath(Integer fileTypeId){ SysParamPo sysmParam = sysParamService.getByParamKey(SysParamKey.FC_UPLOAD_ADDRESS.value); String filePath = Objects.nonNull(sysmParam) ? sysmParam.getParamValue() : ""; return filePath + fileTypeId + File.separator; } }

壓縮下載工具類

package com.huajin.jgoms.util; import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.List;import java.util.Objects;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; import com.huajin.baymax.logger.XMsgError;import com.huajin.baymax.logger.Xlogger; /** * 壓縮下載工具類 * * @author hongwei.lian * @date 2018年9月6日 下午6:34:56 */public class CompressDownloadUtil {  private CompressDownloadUtil() {}  /** * 設(shè)置下載響應(yīng)頭 * * @param response * @return  * @author hongwei.lian * @date 2018年9月7日 下午3:01:59 */ public static HttpServletResponse setDownloadResponse(HttpServletResponse response, String downloadName) { response.reset(); response.setCharacterEncoding("utf-8"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;fileName*=UTF-8''"+ downloadName); return response; }  /** * 字符串轉(zhuǎn)換為整型數(shù)組 * * @param param * @return  * @author hongwei.lian * @date 2018年9月6日 下午6:38:39 */ public static Integer[] toIntegerArray(String param) { return Arrays.stream(param.split(","))  .map(Integer::valueOf)  .toArray(Integer[]::new); }  /** * 將多個(gè)文件壓縮到指定輸出流中 * * @param files 需要壓縮的文件列表 * @param outputStream 壓縮到指定的輸出流 * @author hongwei.lian * @date 2018年9月7日 下午3:11:59 */ public static void compressZip(List<File> files, OutputStream outputStream) { ZipOutputStream zipOutStream = null; try { //-- 包裝成ZIP格式輸出流 zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); // -- 設(shè)置壓縮方法 zipOutStream.setMethod(ZipOutputStream.DEFLATED); //-- 將多文件循環(huán)寫入壓縮包 for (int i = 0; i < files.size(); i++) { File file = files.get(i); FileInputStream filenputStream = new FileInputStream(file); byte[] data = new byte[(int) file.length()]; filenputStream.read(data); //-- 添加ZipEntry,并ZipEntry中寫入文件流,這里,加上i是防止要下載的文件有重名的導(dǎo)致下載失敗 zipOutStream.putNextEntry(new ZipEntry(i + file.getName())); zipOutStream.write(data); filenputStream.close(); zipOutStream.closeEntry(); } } catch (IOException e) { Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e)); } finally { try { if (Objects.nonNull(zipOutStream)) { zipOutStream.flush(); zipOutStream.close(); } if (Objects.nonNull(outputStream)) { outputStream.close(); } } catch (IOException e) { Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e)); } } }  /** * 下載文件 * * @param outputStream 下載輸出流 * @param zipFilePath 需要下載文件的路徑 * @author hongwei.lian * @date 2018年9月7日 下午3:27:08 */ public static void downloadFile(OutputStream outputStream, String zipFilePath) { File zipFile = new File(zipFilePath); if (!zipFile.exists()) { //-- 需要下載壓塑包文件不存在 return ; } FileInputStream inputStream = null; try { inputStream = new FileInputStream(zipFile); byte[] data = new byte[(int) zipFile.length()]; inputStream.read(data); outputStream.write(data); outputStream.flush(); } catch (IOException e) { Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadZip", e)); } finally { try { if (Objects.nonNull(inputStream)) { inputStream.close(); } if (Objects.nonNull(outputStream)) { outputStream.close(); } } catch (IOException e) { Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadZip", e)); } } }  /** * 刪除指定路徑的文件 * * @param filepath  * @author hongwei.lian * @date 2018年9月7日 下午3:44:53 */ public static void deleteFile(String filepath) { File file = new File(filepath); deleteFile(file); }  /** * 刪除指定文件 * * @param file  * @author hongwei.lian * @date 2018年9月7日 下午3:45:58 */ public static void deleteFile(File file) { //-- 路徑為文件且不為空則進(jìn)行刪除  if (file.isFile() && file.exists()) {  file.delete();  }  } }

以上是“java如何實(shí)現(xiàn)多文件壓縮下載”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI