java文件批量上传、zip方式批量下载
WEB项目:
后台代码:
1 package com.achong.controller; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.io.OutputStream; 11 import java.util.ArrayList; 12 import java.util.List; 13 import java.util.UUID; 14 15 import javax.servlet.ServletContext; 16 import javax.servlet.ServletException; 17 import javax.servlet.http.HttpServletRequest; 18 import javax.servlet.http.HttpServletResponse; 19 import javax.servlet.http.HttpSession; 20 21 import org.apache.tools.zip.ZipEntry; 22 import org.apache.tools.zip.ZipOutputStream; 23 import org.springframework.http.HttpHeaders; 24 import org.springframework.http.HttpStatus; 25 import org.springframework.http.ResponseEntity; 26 import org.springframework.stereotype.Controller; 27 import org.springframework.web.bind.annotation.RequestMapping; 28 import org.springframework.web.bind.annotation.RequestParam; 29 import org.springframework.web.multipart.MultipartFile; 30 31 @Controller 32 public class HelloHandler { 33 34 @RequestMapping("/hello") 35 public String hello(){ 36 return "success"; 37 } 38 39 /** 40 * javaWeb: 41 * 1、commons-fileupload.jar commons-io.jar 42 * 2、解析当前请求 List<FileItem> items = servletFileUpload.parse(request); 43 * 3、遍历每一个items,文件项,普通项 44 * 4、如果是文件项,写流的上传方法 45 * 46 * SpringMVC: 47 * 1、文件上传也是使用commons-fileupload.jar 48 * 2、配置好文件上传解析器; 49 * 3、 50 * 51 * @return 52 */ 53 @RequestMapping("/upload") 54 public String upload(@RequestParam("fileName")String fileName, 55 @RequestParam("photo")MultipartFile[] file){ 56 //保存 57 System.out.println("普通项的值:"+fileName); 58 for (MultipartFile multipartFile : file) { 59 if(multipartFile!=null&&!multipartFile.isEmpty()){ 60 File file2 = new File("C:/Users/Administrator/Desktop/上传下载测试/"+multipartFile.getOriginalFilename()); 61 try { 62 multipartFile.transferTo(file2); 63 } catch (IllegalStateException | IOException e) { 64 // TODO Auto-generated catch block 65 e.printStackTrace(); 66 } 67 } 68 } 69 return "success"; 70 } 71 72 @RequestMapping("/singleDownload") 73 public ResponseEntity<byte[]> downloadImg(HttpSession session) throws IOException{ 74 //=============造响应体============= 75 //1、创建一个ResponseEntity对象。这个对象里面既有响应头还有响应体; 76 ServletContext servletContext = session.getServletContext(); 77 //1、获取到图片的流,直接交给浏览器;ServletContext.可以从当前项目下获取资源 78 //2、获取到图片的流 79 InputStream is = servletContext.getResourceAsStream("/Desert.jpg"); 80 //创建一个和流一样多的数组 81 byte[] body = new byte[is.available()]; 82 //3、将流的数据放在数组里面 83 is.read(body); 84 is.close(); 85 86 //==============造响应头================ 87 HttpHeaders headers = new HttpHeaders(); 88 //文件下载的响应头 89 //按照以前乱码的解决方式; 90 91 //文件名乱码解决 92 String filename="单个图片.jpg"; 93 filename = new String(filename.getBytes("GBK"),"ISO8859-1"); 94 headers.add("Content-Disposition", "attachment; filename="+filename); 95 //第一个参数代表给浏览器的响应数据(响应体) 96 //第二个参数代表当前响应的响应头(定制响应头)MultiValueMap 97 //第三个参数代表当前响应状态码(statusCode)HttpStatus 98 ResponseEntity<byte[]> re = new ResponseEntity<byte[]>(body, headers, HttpStatus.OK); 99 100 return re; 101 } 102 103 /** 104 * 批量打包下载文件生成zip文件下载 105 * 106 */ 107 @RequestMapping("/multDownloadZip") 108 public void downloadFiles(HttpServletRequest request, HttpServletResponse response) 109 throws ServletException, IOException { 110 //获取页面上需要批量下载的链接 111 List<File> files = new ArrayList<File>(); 112 String outFilePath = request.getSession().getServletContext().getRealPath("/") 113 + "upload"; 114 System.out.println(outFilePath); 115 File Allfile = new File(outFilePath); 116 System.out.println("Allfile: " + Allfile.getPath()); 117 if (Allfile.exists()) { 118 //得到项目跟路径upload下所有的文件和目录的绝对路径 119 File[] fileArr = Allfile.listFiles(); 120 for (File file2 : fileArr) { 121 files.add(file2); 122 } 123 } 124 125 String fileName = UUID.randomUUID().toString() + ".zip"; 126 // 在服务器端创建打包下载的临时文件 127 System.out.println("outFilePath: " + outFilePath); 128 createFile(outFilePath, fileName); 129 File file = new File(outFilePath + "\\" + fileName); 130 // 文件输出流 131 FileOutputStream outStream = new FileOutputStream(file); 132 /* 133 * 压缩流 134 * 需要导包:import org.apache.tools.zip.ZipOutputStream; 135 */ 136 ZipOutputStream toClient = new ZipOutputStream(outStream); 137 toClient.setEncoding("gbk"); 138 zipFile(files, toClient); 139 toClient.close(); 140 outStream.close(); 141 this.downloadFile(file, response, true); 142 } 143 144 // 创建文件 145 public void createFile(String path, String fileName) { 146 // path表示你所创建文件的路径, fileName为文件名 147 File file = new File(path, fileName); 148 System.out.println(file.getPath()); 149 if (!file.exists()) { 150 try { 151 file.createNewFile(); 152 } catch (IOException e) { 153 e.printStackTrace(); 154 } 155 } 156 157 } 158 159 /** 160 * 压缩文件列表中的文件 161 * 162 * @param files 163 * @param outputStream 164 * @throws IOException 165 */ 166 public static void zipFile(List<File> files, ZipOutputStream outputStream) throws IOException, ServletException { 167 try { 168 int size = files.size(); 169 // 压缩列表中的文件 170 for (int i = 0; i < size; i++) { 171 File file = (File) files.get(i); 172 zipFile(file, outputStream); 173 } 174 } catch (IOException e) { 175 throw e; 176 } 177 } 178 179 /** 180 * 将文件写入到zip文件中 181 * 182 * @param inputFile 183 * @param outputstream 184 * @throws Exception 185 */ 186 public static void zipFile(File inputFile, ZipOutputStream outputstream) throws IOException, ServletException { 187 try { 188 if (inputFile.exists()) { 189 if (inputFile.isFile()) { 190 FileInputStream inStream = new FileInputStream(inputFile); 191 BufferedInputStream bInStream = new BufferedInputStream(inStream); 192 /* 193 * 需要导包:import org.apache.tools.zip.ZipEntry; 194 */ 195 ZipEntry entry = new ZipEntry(inputFile.getName()); 196 outputstream.putNextEntry(entry); 197 198 final int MAX_BYTE = 10 * 1024 * 1024; // 最大的流为10M 199 long streamTotal = 0; // 接受流的容量 200 int streamNum = 0; // 流需要分开的数量 201 int leaveByte = 0; // 文件剩下的字符数 202 byte[] inOutbyte; // byte数组接受文件的数据 203 204 streamTotal = bInStream.available(); // 通过available方法取得流的最大字符数 205 streamNum = (int) Math.floor(streamTotal / MAX_BYTE); // 取得流文件需要分开的数量 206 leaveByte = (int) streamTotal % MAX_BYTE; // 分开文件之后,剩余的数量 207 208 if (streamNum > 0) { 209 for (int j = 0; j < streamNum; ++j) { 210 inOutbyte = new byte[MAX_BYTE]; 211 // 读入流,保存在byte数组 212 bInStream.read(inOutbyte, 0, MAX_BYTE); 213 outputstream.write(inOutbyte, 0, MAX_BYTE); // 写出流 214 } 215 } 216 // 写出剩下的流数据 217 inOutbyte = new byte[leaveByte]; 218 bInStream.read(inOutbyte, 0, leaveByte); 219 outputstream.write(inOutbyte); 220 outputstream.closeEntry(); // Closes the current ZIP entry 221 // and positions the stream for 222 // writing the next entry 223 bInStream.close(); // 关闭 224 inStream.close(); 225 } 226 } else { 227 throw new ServletException("文件不存在!"); 228 } 229 } catch (IOException e) { 230 throw e; 231 } 232 } 233 234 /** 235 * 下载文件 236 * 237 * @param file 238 * @param response 239 */ 240 public void downloadFile(File file, HttpServletResponse response, boolean isDelete) { 241 try { 242 // 以流的形式下载文件。 243 BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath())); 244 byte[] buffer = new byte[fis.available()]; 245 fis.read(buffer); 246 fis.close(); 247 // 清空response 248 response.reset(); 249 OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); 250 response.setContentType("application/octet-stream"); 251 response.setHeader("Content-Disposition", 252 "attachment;filename=" + new String(file.getName().getBytes("UTF-8"), "ISO-8859-1")); 253 toClient.write(buffer); 254 toClient.flush(); 255 toClient.close(); 256 if (isDelete) { 257 file.delete(); // 是否将生成的服务器端文件删除 258 } 259 } catch (IOException ex) { 260 ex.printStackTrace(); 261 } 262 } 263 }
index页面:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 <% 9 pageContext.setAttribute("ctx", request.getContextPath()); 10 %> 11 </head> 12 <body> 13 <a href="hello">Hello</a><br/> 14 <!--相对路径容易出问题,我们都推荐写绝对路径。 15 base:为所有相对路径指定新的标准; --> 16 <hr/> 17 <!-- 18 1、上传文件的表单enctype="multipart/form-data" 19 --> 20 <form action="${ctx }/upload" method="post" enctype="multipart/form-data"> 21 <input type="file" name="photo"/> 22 <input type="file" name="photo"/> 23 <input type="file" name="photo"/> 24 <input type="file" name="photo"/> 25 描述:<input type="text" name="fileName"/> 26 <input type="submit" value="上传"/> 27 </form> 28 <a href="${ctx }/singleDownload">下载单个</a><br/> 29 <a href="${ctx }/multDownloadZip">批量下载</a> 30 </body> 31 </html>
success页面:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <h1>成功!</h1> 11 </body> 12 </html>
WebContent目录结构: