zoukankan      html  css  js  c++  java
  • 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显示如下:

      让我们增加一点难度,我们要下载的文件是一个中文名字的文件。由于在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码表中不存在的编码时,会将该数据编码成'?',结束后数据就变成中文和'?'的混合。发到客户端后显示时再次查阅码表,将所有的'?'替换成'?'的编码,就会丢失数据。向这种细节只需要记住一点:字节流可以处理任意类型的数据,字符流只能处理字符数据。

  • 相关阅读:
    rest framework 认证 权限 频率
    rest framework 视图,路由
    rest framework 序列化
    10.3 Vue 路由系统
    10.4 Vue 父子传值
    10.2 Vue 环境安装
    10.1 ES6 的新增特性以及简单语法
    Django 跨域请求处理
    20190827 On Java8 第十四章 流式编程
    20190825 On Java8 第十三章 函数式编程
  • 原文地址:https://www.cnblogs.com/yyz666/p/4046063.html
Copyright © 2011-2022 走看看