文件下载,转载路径:http://www.cnblogs.com/xdp-gacl/p/3789624.html

来源:互联网 发布:花生壳软件联系电话 编辑:程序博客网 时间:2024/05/18 00:17

2.4、文件下载

  文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

文件下载功能的实现思路:

  1.获取要下载的文件的绝对路径

  2.获取要下载的文件名

  3.设置content-disposition响应头控制浏览器以下载的形式打开文件

  4.获取要下载的文件输入流

  5.创建数据缓冲区

  6.通过response对象获取OutputStream流

  7.将FileInputStream流写入到buffer缓冲区

  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

范例:使用Response实现文件下载

复制代码
 1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15  * @author gacl16  * 文件下载17  */18 public class ResponseDemo02 extends HttpServlet {19 20     public void doGet(HttpServletRequest request, HttpServletResponse response)21             throws ServletException, IOException {22         downloadFileByOutputStream(response);//下载文件,通过OutputStream流23     }24 25     /**26      * 下载文件,通过OutputStream流27      * @param response28      * @throws FileNotFoundException29      * @throws IOException30      */31     private void downloadFileByOutputStream(HttpServletResponse response)32             throws FileNotFoundException, IOException {33         //1.获取要下载的文件的绝对路径34         String realPath = this.getServletContext().getRealPath("/download/1.JPG");35         //2.获取要下载的文件名36         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);37         //3.设置content-disposition响应头控制浏览器以下载的形式打开文件38         response.setHeader("content-disposition", "attachment;filename="+fileName);39         //4.获取要下载的文件输入流40         InputStream in = new FileInputStream(realPath);41         int len = 0;42         //5.创建数据缓冲区43         byte[] buffer = new byte[1024];44         //6.通过response对象获取OutputStream流45         OutputStream out = response.getOutputStream();46         //7.将FileInputStream流写入到buffer缓冲区47         while ((len = in.read(buffer)) > 0) {48         //8.使用OutputStream将缓冲区的数据输出到客户端浏览器49             out.write(buffer,0,len);50         }51         in.close();52     }53 54     public void doPost(HttpServletRequest request, HttpServletResponse response)55             throws ServletException, IOException {56         doGet(request, response);57     }58 }
复制代码

运行结果如下所示:

  

 范例:使用Response实现中文文件下载

  下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。

复制代码
 1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15  * @author gacl16  * 文件下载17  */18 public class ResponseDemo02 extends HttpServlet {19 20     public void doGet(HttpServletRequest request, HttpServletResponse response)21             throws ServletException, IOException {22         downloadChineseFileByOutputStream(response);//下载中文文件23     }24 25     /**26      * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码27      * @param response28      * @throws FileNotFoundException29      * @throws IOException30      */31     private void downloadChineseFileByOutputStream(HttpServletResponse response)32             throws FileNotFoundException, IOException {33         String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径34         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名35         //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码36         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));37         InputStream in = new FileInputStream(realPath);//获取文件输入流38         int len = 0;39         byte[] buffer = new byte[1024];40         OutputStream out = response.getOutputStream();41         while ((len = in.read(buffer)) > 0) {42             out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器43         }44         in.close();45     }46     47     public void doPost(HttpServletRequest request, HttpServletResponse response)48             throws ServletException, IOException {49         doGet(request, response);50     }51 }
复制代码

运行结果如下所示:

  

  文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

范例:使用PrintWriter流下载文件

复制代码
 1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15  * @author gacl16  * 文件下载17  */18 public class ResponseDemo02 extends HttpServlet {19 20     public void doGet(HttpServletRequest request, HttpServletResponse response)21             throws ServletException, IOException {22         downloadFileByPrintWriter(response);//下载文件,通过PrintWriter流23     }24 25     /**26      * 下载文件,通过PrintWriter流,虽然也能够实现下载,但是会导致数据丢失,因此不推荐使用PrintWriter流下载文件27      * @param response28      * @throws FileNotFoundException29      * @throws IOException30      */31     private void downloadFileByPrintWriter(HttpServletResponse response)32             throws FileNotFoundException, IOException {33         String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径34         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名35         //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码36         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));37         FileReader in = new FileReader(realPath);38         int len = 0;39         char[] buffer = new char[1024];40         PrintWriter out = response.getWriter();41         while ((len = in.read(buffer)) > 0) {42             out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器43         }44         in.close();45     }46     47     public void doPost(HttpServletRequest request, HttpServletResponse response)48             throws ServletException, IOException {49         doGet(request, response);50     }51 }
复制代码

运行结果如下:

  

正常弹出下载框,此时我们点击【保存】按钮将文件下载下来,如下所示:

  

  可以看到,只下载了5.25MB,而这张图片的原始大小却是

  

  这说明在下载的时候数据丢失了,所以下载不完全,所以这张图片虽然能够正常下载下来,但是却是无法打开的,因为丢失掉了部分数据,如下所示:

  

   所以使用PrintWriter流处理字节数据,会导致数据丢失,这一点千万要注意,因此在编写下载文件功能时,要使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。


阅读全文
0 0
原创粉丝点击