最近做了一個ABTest的應用,使用者希望對ABTest的結果能夠打包批量進行下載,這個時候就需要先對下載的多個檔案進行壓縮打包,再進行下載。
@RequestMapping("/download")public Object export(HttpServletRequest request, HttpServletResponse response, @RequestParam String batchId,) throws IOException { List<UserInfo> list = userDao.getUsers(batchId); String tmpdir = System.getProperty("java.io.tmpdir"); if(StringUtils.isEmpty(tmpdir)){ logger.info("tmpdir is empty, use ServletContextPath"); tmpdir = request.getServletContext().getContextPath(); } logger.info("export tmpdir:{}", tmpdir); File tempDir = new File(tmpdir+File.separator+"download"); if(!tempDir.exists()){ boolean success = tempDir.mkdirs(); logger.info("create tempDir:{}, success:{}", tempDir.getAbsolutePath(), success); } File zipFile = new File(tempDir, String.format("%s.zip", batchId)); //壓縮後的檔案 OutputStream out = null; InputStream in = null; try { convert(list, zipFile); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=" + zipFile.getName()); out = response.getOutputStream(); in = new FileInputStream(zipFile); IoUtils.copy(in, out); } catch (IOException e) { logger.error("export file error", e); }finally { IoUtils.closeQuietly(out); IoUtils.closeQuietly(in); }}
private void convert(List<UserInfo> list, File zipFile){ ZipOutputStream zipOut = null; try { zipOut = new ZipOutputStream(new FileOutputStream(zipFile)); for (UserInfo info : list){ addZipEntry(zipOut, info.getId()+".txt", info.getName()+"\t"+info.getPassword()); } zipOut.flush(); } catch (Exception e) { logger.error("export data failed, type:"+type+", batchId:"+batchId, e); throw new RuntimeException("export data failed, type:"+type+", batchId:"+batchId, e); }finally { IoUtils.closeQuietly(zipOut); }}
private void addZipEntry(ZipOutputStream zipOut, String name, String data) throws IOException { zipOut.putNextEntry(new ZipEntry(name)); zipOut.setComment(""); if(StringUtils.isEmpty(data)){ data = " "; } zipOut.write(data.getBytes("UTF-8"));}