思路:一边压缩一边下载,将多个文件逐一写入到压缩文件中
@ResponseBody @GetMapping("/download") public void downloadFiles(HttpServletRequest request, HttpServletResponse response){ /* * test * */ List<String> list = new ArrayList<>(); list.add("F:\\1\\test\\2\\1.exe"); list.add("F:\\1\\test\\2\\2.exe"); list.add("F:\\1\\test\\2\\3.exe"); //响应头的设置 response.reset(); response.setCharacterEncoding("utf-8"); response.setContentType("application/octet-stream;charset=utf-8");// 设置response内容的类型 //设置压缩包的名字 //解决不同浏览器压缩包名字含有中文时乱码的问题 String downloadName = "test.zip"; String agent = request.getHeader("USER-AGENT"); ZipOutputStream zipos = null; //循环将文件写入压缩流 DataOutputStream os = null; try { if (agent.contains("MSIE")||agent.contains("Trident")) { downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8"); } else { downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1"); } response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\""); //设置压缩流:直接写入response,实现边压缩边下载 zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法 for(int i = 0; i < list.size(); i++ ){ InputStream is = null; try{ File file = new File(list.get(i)); if(file.exists()){ //添加ZipEntry,并ZipEntry中写入文件流 //这里,加上i是防止要下载的文件有重名的导致下载失败 zipos.putNextEntry(new ZipEntry(i + "_" + file.getName())); os = new DataOutputStream(zipos); is = new FileInputStream(file); byte[] b = new byte[1024]; int length = 0; while((length = is.read(b))!= -1){ os.write(b, 0, length); } } } finally { if(null != is){ is.close(); } zipos.closeEntry(); } } if(null != os){ os.flush(); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭流 try { if(null != os){ os.close(); } if(null != zipos){ zipos.close(); } } catch (IOException e) { e.printStackTrace(); } } }