java下载文件

时间:5年前   阅读:3969

本文详解java文件下载总结:

  1、列出提供下载的文件资源

  要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。

  ListFileServlet代码如下:

public class ListFileServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //获取上传文件的目录
        String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        //存储要下载的文件名
        Map<String, String> fileMap = new HashMap<String, String>();
        //递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
        fileList(new File(uploadFilePath),fileMap);
        //将Map集合发送到listfile.jsp页面进行显示
        request.setAttribute("fileMap", fileMap);
        request.getRequestDispatcher("/listfile.jsp").forward(request, response);

    }
    //递归遍历指定目录下的所有文件
    public void fileList(File file,Map fileMap){
        //如果file代表的不是一个文件,而是一个目录
        if(!file.isFile()){
            //列出该目录下的所有文件和目录
            File[] files = file.listFiles();
            //遍历files[]数组
            for (File file2 : files) {
                System.out.println(file2.getName());
                //递归
                fileList(file2, fileMap);
            }
        }else{
              /* 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
                 file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi
                  那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分
              */
            String realName = file.getName().substring(file.getName().lastIndexOf("_")+1);
            //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
            fileMap.put(file.getName(), realName);
        }
    }
}

说明一下,一般文件路径在数据库中保存,然后再数据库中查询结果在页面显示。

  listfile.jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <!DOCTYPE HTML>
 <html>
   <head>
     <title>下载文件显示页面</title>
  </head>
   
   <body>
      <!-- 遍历Map集合 -->
     <c:forEach var="me" items="${fileMap}">
         <c:url value="/servlet/downLoadServlet" var="downurl">
             <c:param name="filename" value="${me.key}"></c:param>
         </c:url>
         ${me.value}<a href="${downurl}">下载</a>
         <br/>
     </c:forEach>
   </body>
 </html>

2、文件下载

  DownLoadServlet的代码如下:

public class DownLoadServlet extends HttpServlet{

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //得到要下载的文件名
        String fileName = request.getParameter("filename");
        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
        //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
        String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
        //        处理文件名
         String realname = fileName.substring(fileName.indexOf("_")+1);
        //通过文件名找出文件的所在目录
        String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
        //得到要下载的文件
        File file = new File(path+File.separator+fileName);
        //如果文件不存在
        if(!file.exists()){
            request.setAttribute("message", "您要下载的资源已被删除!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }
        
         //设置响应头,控制浏览器下载该文件
         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
         //读取要下载的文件,保存到文件输入流
         FileInputStream fis = new FileInputStream(path + File.separator + fileName);
         //创建输出流
         OutputStream fos = response.getOutputStream();
         //设置缓存区
         ByteBuffer buffer = ByteBuffer.allocate(1024);
         //输入通道
         FileChannel readChannel = fis.getChannel();
         //输出通道
         FileChannel writeChannel = ((FileOutputStream)fos).getChannel();
         while(true){
             buffer.clear();
             int len = readChannel.read(buffer);//读入数据
             if(len < 0){
                 break;//传输结束
             }
             buffer.flip();
             writeChannel.write(buffer);//写入数据
         }
         //关闭输入流
         fis.close();
         //关闭输出流
         fos.close();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    //通过文件名和存储上传文件根目录找出要下载的文件的所在路径
    public String findFileSavePathByFileName(String fileName,String fileSaveRootPath){
        int hashcode = fileName.hashCode();
        int dir1 = hashcode&0xf;
        int dir2 = (hashcode&0xf0)>>4;
        String dir = fileSaveRootPath + "\\" + dir1 + "\\" + dir2;
        File file = new File(dir);
        if(!file.exists()){
            file.mkdirs();
        }
        return dir;
    }
}

3、如果IO成为系统的瓶颈,可以考虑使用NIO来实现下载,提供系统性能,改进后的DownloadServlet代码如下:

public class DownLoadServlet1 extends HttpServlet{

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //得到要下载的文件名
        String fileName = request.getParameter("filename");
        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
        //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
        String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
        //        处理文件名
         String realname = fileName.substring(fileName.indexOf("_")+1);
        //通过文件名找出文件的所在目录
        String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
        //得到要下载的文件
        File file = new File(path+File.separator+fileName);
        //如果文件不存在
        if(!file.exists()){
            request.setAttribute("message", "您要下载的资源已被删除!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }
        
         //设置响应头,控制浏览器下载该文件
         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
         //读取要下载的文件,保存到文件输入流
         FileInputStream in = new FileInputStream(path + File.separator + fileName);
         //创建输出流
         OutputStream os = response.getOutputStream();
         //设置缓存区
         byte[] bytes = new byte[1024];
         int len = 0;
         while((len = in.read(bytes))>0){
             os.write(bytes);
         }
         //关闭输入流
         in.close();
         //关闭输出流
         os.close();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    //通过文件名和存储上传文件根目录找出要下载的文件的所在路径
    public String findFileSavePathByFileName(String fileName,String fileSaveRootPath){
        int hashcode = fileName.hashCode();
        int dir1 = hashcode&0xf;
        int dir2 = (hashcode&0xf0)>>4;
        String dir = fileSaveRootPath + "\\" + dir1 + "\\" + dir2;
        File file = new File(dir);
        if(!file.exists()){
            file.mkdirs();
        }
        return dir;
    }
}

本文最后 2019-07-12 09:58:50 编辑

本站声明:网站内容来源于网络,如有侵权,请联系我们https://www.qiquanji.com,我们将及时处理。

微信扫码关注

更新实时通知

上一篇:上证50ETF期权优势有哪些?

下一篇:Java的arraylist排序

网友评论

请先 登录 再评论,若不是会员请先 注册