java web实现文件下载

本文介绍了如何在Java Web环境中实现文件下载功能。通过ListFileServlet和DownLoadServlet的代码示例,详细阐述了配置及文件处理的过程。
我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。

  ListFileServlet的代码如下:

1 package me.gacl.web.controller;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13 * @ClassName: ListFileServlet
14 * @Description: 列出Web系统中所有下载文件
15 * @author: 孤傲苍狼
16 * @date: 2015-1-4 下午9:54:40
17 *
18 */ 
19 public class ListFileServlet extends HttpServlet {
20 
21     public void doGet(HttpServletRequest request, HttpServletResponse response)
22             throws ServletException, IOException {
23         //获取上传文件的目录
24         String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
25         //存储要下载的文件名
26         Map<String,String> fileNameMap = new HashMap<String,String>();
27         //递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
28         listfile(new File(uploadFilePath),fileNameMap);//File既可以代表一个文件也可以代表一个目录
29         //将Map集合发送到listfile.jsp页面进行显示
30         request.setAttribute("fileNameMap", fileNameMap);
31         request.getRequestDispatcher("/listfile.jsp").forward(request, response);
32     }
33     
34     /**
35     * @Method: listfile
36     * @Description: 递归遍历指定目录下的所有文件
37     * @Anthor:孤傲苍狼
38     * @param file 即代表一个文件,也代表一个文件目录
39     * @param map 存储文件名的Map集合
40     */ 
41     public void listfile(File file,Map<String,String> map){
42         //如果file代表的不是一个文件,而是一个目录
43         if(!file.isFile()){
44             //列出该目录下的所有文件和目录
45             File files[] = file.listFiles();
46             //遍历files[]数组
47             for(File f : files){
48                 //递归
49                 listfile(f,map);
50             }
51         }else{
52             /**
53              * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
54                 file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi
55                 那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分
56              */
57             String realName = file.getName().substring(file.getName().indexOf("_")+1);
58             //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
59             map.put(file.getName(), realName);
60         }
61     }
62     
63     public void doPost(HttpServletRequest request, HttpServletResponse response)
64             throws ServletException, IOException {
65         doGet(request, response);
66     }
67 }

这里简单说一下ListFileServlet中listfile方法,listfile方法是用来列出目录下的所有文件的,listfile方法内部用到了递归,在实际开发当中,我们肯定会在数据库创建一张表,里面会存储上传的文件名以及文件的具体存放目录,我们通过查询表就可以知道文件的具体存放目录,是不需要用到递归操作的,这个例子是因为没有使用数据库存储上传的文件名和文件的具体存放位置,而上传文件的存放位置又使用了散列算法打散存放,所以需要用到递归,在递归时,将获取到的文件名存放到从外面传递到listfile方法里面的Map集合当中,这样就可以保证所有的文件都存放在同一个Map集合当中。

  在Web.xml文件中配置ListFileServlet

1 <servlet>
2      <servlet-name>ListFileServlet</servlet-name>
3      <servlet-class>me.gacl.web.controller.ListFileServlet</servlet-class>
4 </servlet>
5  
6 <servlet-mapping>
7      <servlet-name>ListFileServlet</servlet-name>
8     <url-pattern>/servlet/ListFileServlet</url-pattern>
9 </servlet-mapping>    
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 3 <!DOCTYPE HTML>
 4 <html>
 5   <head>
 6     <title>下载文件显示页面</title>
 7   </head>
 8   
 9   <body>
10       <!-- 遍历Map集合 -->
11     <c:forEach var="me" items="${fileNameMap}">
12         <c:url value="/servlet/DownLoadServlet" var="downurl">
13             <c:param name="filename" value="${me.key}"></c:param>
14         </c:url>
15         ${me.value}<a href="${downurl}">下载</a>
16         <br/>
17     </c:forEach>
18   </body>
19 </html>

  编写一个用于处理文件下载的Servlet,DownLoadServlet的代码如下:

 1 package me.gacl.web.controller;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.IOException;
 6 import java.io.OutputStream;
 7 import java.net.URLEncoder;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 
13 public class DownLoadServlet extends HttpServlet {
14 
15     
16     public void doGet(HttpServletRequest request, HttpServletResponse response)
17             throws ServletException, IOException {
18         //得到要下载的文件名
19         String fileName = request.getParameter("filename");  //23239283-92489-阿凡达.avi
20         fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
21         //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
22         String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
23         //通过文件名找出文件的所在目录
24         String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
25         //得到要下载的文件
26         File file = new File(path + "\\" + fileName);
27         //如果文件不存在
28         if(!file.exists()){
29             request.setAttribute("message", "您要下载的资源已被删除!!");
30             request.getRequestDispatcher("/message.jsp").forward(request, response);
31             return;
32         }
33         //处理文件名
34         String realname = fileName.substring(fileName.indexOf("_")+1);
35         //设置响应头,控制浏览器下载该文件
36         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
37         //读取要下载的文件,保存到文件输入流
38         FileInputStream in = new FileInputStream(path + "\\" + fileName);
39         //创建输出流
40         OutputStream out = response.getOutputStream();
41         //创建缓冲区
42         byte buffer[] = new byte[1024];
43         int len = 0;
44         //循环将输入流中的内容读取到缓冲区当中
45         while((len=in.read(buffer))>0){
46             //输出缓冲区的内容到浏览器,实现文件下载
47             out.write(buffer, 0, len);
48         }
49         //关闭文件输入流
50         in.close();
51         //关闭输出流
52         out.close();
53     }
54     
55     /**
56     * @Method: findFileSavePathByFileName
57     * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径
58     * @Anthor:孤傲苍狼
59     * @param filename 要下载的文件名
60     * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录
61     * @return 要下载的文件的存储目录
62     */ 
63     public String findFileSavePathByFileName(String filename,String saveRootPath){
64         int hashcode = filename.hashCode();
65         int dir1 = hashcode&0xf;  //0--15
66         int dir2 = (hashcode&0xf0)>>4;  //0-15
67         String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
68         File file = new File(dir);
69         if(!file.exists()){
70             //创建目录
71             file.mkdirs();
72         }
73         return dir;
74     }
75     
76     public void doPost(HttpServletRequest request, HttpServletResponse response)
77             throws ServletException, IOException {
78         doGet(request, response);
79     }
80 }
 在Web.xml文件中配置DownLoadServlet

1 <servlet>
2       <servlet-name>DownLoadServlet</servlet-name>
3       <servlet-class>me.gacl.web.controller.DownLoadServlet</servlet-class>
4 </servlet>
5  
6 <servlet-mapping>
7       <servlet-name>DownLoadServlet</servlet-name>
8       <url-pattern>/servlet/DownLoadServlet</url-pattern>
9 </servlet-mapping>    



内容概要:本文详细比较了GPU、TPU专用AI芯片在大模型推理优化方面的性能、成本及适用场景。GPU以其强大的并行计算能力和高带宽显存,适用于多种类型的神经网络模型和计算任务,尤其适合快速原型开发和边缘计算设备。TPU专为机器学习设计,擅长处理大规模矩阵运算密集型任务,如Transformer模型的推理,具有高吞吐量和低延迟特性,适用于自然语言处理和大规模数据中心的推理任务。专用AI芯片通过高度定制化架构,针对特定神经网络模型进行优化,如卷积神经网络(CNN),在处理特定任务时表现出色,同时具备低功耗和高能效比的优势,适用于边缘计算设备。文章还介绍了各自的优化工具和框架,如CUDA、TensorRT、TPU编译器等,并从硬件成本、运营成本和开发成本三个角度进行了成本对比。 适合人群:从事人工智能、深度学习领域的研究人员和技术人员,尤其是对大模型推理优化感兴趣的读者。 使用场景及目标:①帮助读者理解GPU、TPU和专用AI芯片在大模型推理中的优缺点;②为选择适合的硬件平台提供参考依据,以实现最优的推理性能和成本效益;③介绍各种优化工具和框架,帮助开发者高效部署和优化模型。 其他说明:本文不仅涵盖了硬件架构特性,还深入探讨了优化技术和应用场景,旨在为读者提供全面的技术参考。在选择硬件平台时,需综合考虑具体任务需求、预算限制及开发资源等因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值