一、文件下载简述
1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息
(1)response.setContentType("application/force-download");
(2)response.setContentLength(fis.available());
(3)response.setHeader("Content-Disposition","attachment;filename="+filename);
2.如果需要下载的文件名是中文,则还需要特殊对待
(1)如果使用get方式向Servlet进行的请求,需要编码才能获取正确的文件名
String filename=request.getParameter("filename");
filename=new String(filename.getBytes("iso-8859-1"),"utf-8");
(2)必须通知浏览器实际文件名是中文的,但是必须要经过编码才行。
filename=URLEncoder.encode(filename,"utf-8");
注:不经过编码的中文文件名能够成功下载,但是文件名是乱码。
3.文件下载既能够是GET方式的请求,也可以是POST方式的请求。但是文件上传必须是GET方式的请求。
4.使用多线程文件下载和断点下载都需要的核心类:RandomAccessFile类。
API1.6对其描述为:
此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。
通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。
二、单线程文件下载(网页上从服务器下载)
1.JSP文件
<a href="<c:url value='/downloadFromServer?filename=动漫.jpg'/>">动漫.jpg下载</a><br/>
2.Servlet响应请求
package com.kdyzm.servlet.singlethread; /* * 从服务器上进行单线程下载示例。 * 非断点下载 * 下载既可以是get方式也可以是post方式。 */ import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownloadFromServer extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String filename=request.getParameter("filename"); filename=new String(filename.getBytes("iso-8859-1"),"utf-8"); //第一步:设置相应类型 response.setContentType("application/force-download"); //第二步:读取文件 String path=this.getServletContext().getRealPath("/resource")+"/"+filename; FileInputStream fis=new FileInputStream(path); //第三步:设置响应头,对文件名进行URL编码 filename=URLEncoder.encode(filename,"utf-8"); response.setContentLength(fis.available()); response.setHeader("Content-Disposition","attachment;filename="+filename); //第三步:开始文件复制 OutputStream os=response.getOutputStream(); int length=-1; byte[]buff=new byte[1024*1024]; while((length=fis.read(buff))!=-1) { os.write(buff, 0, length); } os.close(); fis.close(); } }