JAVA WEB 批量文件下载
最近需要这个所以写了一个例子
一般批量下载由以下步骤组成:
1、确定下载的源文件位置
2、对文件进行打包成临时文件,这里会用到递归调用,需要的嵌套的文件夹进行处理,并返回文件保存位置
3、将打包好的文件下载
4、下载完成将打包的临时文件删除
下面的代码中鉴于简单方便,作为例子使用,使用纯的jsp实现下载,没有配置成servlet,
下载时使用JS事件模拟功能直接请求JSP文件方式,如果需要使用servlet方式,
可把jsp中的java代码搬到servlet中
文件打包 zip 代码:
package com.downloadZip; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class DownloadZip { private static int BUF_SIZE = 1024*10; public static void main(String[] args) { try { File f = new DownloadZip().createZip("D:/img","D:/imgs","img"); System.out.println(f.getPath()); } catch (IOException e) { e.printStackTrace(); } } /** * 创建压缩文件 * @param sourcePath 要压缩的文件 * @param zipFilePath 文件存放路徑 * @param zipfileName 压缩文件名称 * @return File * @throws IOException */ public File createZip(String sourcePath ,String zipFilePath,String zipfileName) throws IOException{ //打包文件名称 zipfileName = zipfileName+".zip"; /**在服务器端创建打包下载的临时文件夹*/ File zipFiletmp = new File(zipFilePath+"/tmp"+System.currentTimeMillis()); if(!zipFiletmp.exists() && !(zipFiletmp.isDirectory())){ zipFiletmp.mkdirs(); } File fileName = new File(zipFiletmp,zipfileName); //打包文件 createZip(sourcePath,fileName); return fileName; } /** * 创建ZIP文件 * @param sourcePath 文件或文件夹路径 * @param zipPath 生成的zip文件存在路径(包括文件名) */ public void createZip(String sourcePath, File zipFile) { ZipOutputStream zos = null; try { zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile),BUF_SIZE)); writeZip(new File(sourcePath), "", zos); } catch (FileNotFoundException e) { throw new RuntimeException(e); } finally { try { if (zos != null) { zos.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } /** * 创建ZIP文件 * @param sourcePath 文件或文件夹路径 * @param zipPath 生成的zip文件存在路径(包括文件名) */ public void createZip(String sourcePath, String zipPath) { ZipOutputStream zos = null; try { zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipPath),BUF_SIZE)); writeZip(new File(sourcePath), "", zos); } catch (FileNotFoundException e) { throw new RuntimeException(e); } finally { try { if (zos != null) { zos.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } /** * * @param file * @param parentPath * @param zos */ private void writeZip(File file, String parentPath, ZipOutputStream zos) { if(file.exists()){ if(file.isDirectory()){//处理文件夹 parentPath+=file.getName()+File.separator; File [] files=file.listFiles(); for(File f:files){ writeZip(f, parentPath, zos); } }else{ DataInputStream dis=null; try { dis=new DataInputStream(new BufferedInputStream(new FileInputStream(file))); ZipEntry ze = new ZipEntry(parentPath + file.getName()); zos.putNextEntry(ze); byte [] content=new byte[BUF_SIZE]; int len; while((len=dis.read(content))!=-1){ zos.write(content,0,len); zos.flush(); } zos.closeEntry(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); }finally{ try { if(dis!=null){ dis.close(); } }catch(IOException e){ throw new RuntimeException(e); } } } } } /** * 刪除文件 * @param file * @return * @throws Exception */ public boolean delFile(File file) throws Exception { boolean result = false; if(file.exists()&&file.isFile()) { file.delete(); file.getParentFile().delete(); result = true; } return result; } }
JSP 下载逻辑代码:
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%> <%@ page import="java.net.*"%> <%@ page import="java.io.*"%> <%@ page import="com.downloadZip.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"> <title>Insert title here</title> </head> <body> <% // 创建压缩包并返回压缩包位置 DownloadZip downloadZip = new DownloadZip(); File zipfile = downloadZip.createZip("D:/img","D:/imgs","img"); String path=zipfile.getPath(); // 获取文件名 String fileName=path.substring(path.lastIndexOf("\\")+1); System.out.println(fileName); //制定浏览器头 //如果图片名称是中文需要设置转码 response.setCharacterEncoding("GBK"); response.setContentType("application/x-download");//设置为下载application/x-download response.setHeader("content-disposition", "attachment;fileName="+URLEncoder.encode(fileName, "GBK")); InputStream reader = null; OutputStream outp = null; byte[] bytes = new byte[1024]; int len = 0; try { // 读取文件 reader = new FileInputStream(path); // 写入浏览器的输出流 outp = response.getOutputStream(); while ((len = reader.read(bytes)) > 0) { outp.write(bytes, 0, len); outp.flush(); } out.clear(); out = pageContext.pushBody(); } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { reader.close(); } //这里貌似不能关闭,如果关闭在同一个页面多次点击下载,会报错 //if (outp != null) // outp.close(); downloadZip.delFile(zipfile); } %> </body> </html>
下载页面 代码:JS 代码中使用了JS模拟事件的功能
<!DOCTYPE html> <html> <head> <meta charset="GBK"> <title>Insert title here</title> </head> <body> <input type="button" value="下载" onclick="down()"/> <a id="download" href="dwo.jsp" style="display: none;">下载</a> <script type="text/javascript"> function down(){ var download=document.getElementById("download"); download.href = download.href+"?aa=abs"; alert(download.href); //禁用原来哦 onclick 事件 download.setAttribute("onclick",''); download.click("return false"); // window.open(download.href); } </script> </body> </html>