response小结(二)——文件下载

  我们先来看一个最简单的文件下载的例子:

 1 package com.yyz.response;

 2 

 3 import java.io.FileInputStream;

 4 import java.io.IOException;

 5 import java.io.OutputStream;

 6 

 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 public class ResponseDemo extends HttpServlet {

13 

14     public void doGet(HttpServletRequest request, HttpServletResponse response)

15             throws ServletException, IOException {

16         String realpath = this.getServletContext().getRealPath("/download/1.gif");

17         String filename = realpath.substring(realpath.lastIndexOf("\\")+1);

18         response.setHeader("content-disposition", "attachment;filename="+filename);

19         //服务器通过这个头,告诉浏览器以下载方式打开数据

20         FileInputStream in = new FileInputStream(realpath);

21         int len = 0;

22         byte buffer[]=new byte[1024];

23         OutputStream out = response.getOutputStream();

24         while((len = in.read(buffer))>0){

25             out.write(buffer, 0, len);

26             }

27         in.close();

28         //out不用close,response在销毁的时候服务器会自动关闭与response相关的流。

29 }

30 

31     public void doPost(HttpServletRequest request, HttpServletResponse response)

32             throws ServletException, IOException {

33            doGet(request,response);

34     }

35 }

 该段代码的功能是从服务器端下载图片1.png。目录结构用MyEclipse的package explorer显示如下:

response小结(二)——文件下载

  让我们增加一点难度,我们要下载的文件是一个中文名字的文件。由于在http协议中头文件中的东西只能是ASCII字符,因而通过上述方式(直接将  String realpath = this.getServletContext().getRealPath("/download/1.gif");改为  String realpath = this.getServletContext().getRealPath("/download/图片.gif");)直接拿文件,

会出现乱码问题。附上测试结果:

  要解决这个问题,要用到 URLEncoder类的encode方法:

 1 package com.yyz.response;

 2 

 3 import java.io.FileInputStream;

 4 import java.io.IOException;

 5 import java.io.OutputStream;

 6 import java.net.URLEncoder;

 7 

 8 import javax.servlet.ServletException;

 9 import javax.servlet.http.HttpServlet;

10 import javax.servlet.http.HttpServletRequest;

11 import javax.servlet.http.HttpServletResponse;

12 //中文文件下载时,中文文件名要经过URL编码。

13 public class ResponseDemo extends HttpServlet {

14 

15     public void doGet(HttpServletRequest request, HttpServletResponse response)

16             throws ServletException, IOException {

17         String realpath = this.getServletContext().getRealPath("/download/图片.gif"); 18         String filename = realpath.substring(realpath.lastIndexOf("\\")+1);

19         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8")); 20        //本函数将字符串以 URL 编码

21         FileInputStream in = new FileInputStream(realpath);

22         int len = 0;

23         byte buffer[]=new byte[1024];

24         OutputStream out = response.getOutputStream();

25         while((len = in.read(buffer))>0){

26             out.write(buffer, 0, len);

27             }

28         in.close();

29 }

30 

31     public void doPost(HttpServletRequest request, HttpServletResponse response)

32             throws ServletException, IOException {

33            doGet(request,response);

34     }

35 }

 附上测试结果:

    另外这里有一个小细节需要大家注意:

   不能用FileReader代替FileInputStream。用FileReader会丢失数据,原因是这样的:FileReader是字符流,而图片,媒体文件等的数据都是以01的方式存储,用FileReader读的时候需要查阅一个编码表,如果未指定一种编码,则使用相应平台的默认编码。如在中国的电脑就会去查GB2312。当读到GB2312码表中不存在的编码时,会将该数据编码成'?',结束后数据就变成中文和'?'的混合。发到客户端后显示时再次查阅码表,将所有的'?'替换成'?'的编码,就会丢失数据。向这种细节只需要记住一点:字节流可以处理任意类型的数据,字符流只能处理字符数据。

 

你可能感兴趣的:(response)