Javaweb基础浅聊下载文件

上一篇聊了上传文件,既然是上传,那么自然也是需要有下载文件的。其实再聊上传文件的时候,其导导入了两个jar包,但是只用了一个现在用另一个:

对于这个二进制处理,一般直接使用一个jar进行解析:commons-fileupload-版本号.jarcommons-io-版本号.jar如果需要,私信给我要。

也可以通过下面网址下载:

  • commons-fileupload: 可以从 http://commons.apache.org/proper/commons-fileupload/ 下载。
  • commons-io: 可以从 http://commons.apache.org/proper/commons-io/ 下载。

commons-io-版本号.jar是为下载而服务的。

其也是分三个部分:

  • 第一步:通过HttpServletResponse和HttpServletRequest的一些方法得到一些数据或者参数。

    方法描述
    req.getOutputStream()响应数据流
    req.getServletContext().getResourceAsStream(“资源路径”)资源转为输入流
    req.getServletContext().getMimeType(“路径”);获得资源文件的类型
    resp.setContentType(mimeType);告诉响应数据的类型
  • 第二步:兼容问题,因为有些浏览器对于中文的通过不同的加密进行。

    • 火狐浏览器通过base64加密方式解决
    • 其它的需要通过URLEncoder加密解决
  • 第三步: 这个就需要commons-io jar包中的IOUtils类,然后通过调用其方法。

    方法描述
    IOUtils.copy(resourceAsStream, outputStream)读取输入流中全部的数据,复制给输出流,输出给客户端,如果不写响应参数Content-Disposition就会再网页显示而不是下载。

IOUtils类的方法

因为这个工具类的方法,不是本篇主要演示,所以就直接说一下其有什么方法,也为了省事,直接复制黏贴了别人写的文章

  • 将字节流转换成缓冲字节流
public static InputStream toBufferedInputStream(InputStream input) 
  • 将输入流写入字节数组
public static byte[] toByteArray(InputStream input)
public static byte[] toByteArray(Reader input)
public static byte[] toByteArray(Reader input, String encoding)
public static byte[] toByteArray(String input)

代码:

String filename = "D:" + File.separator + "data.txt"; 
File file = new File(filename); 
InputStream in = new FileInputStream(file);
byte[] array = IOUtils.toByteArray(in);
System.out.println(array.length); //49
  • 将输入流写入字符数组
public static char[] toCharArray(InputStream is)
public static char[] toCharArray(InputStream is, String encoding)
public static char[] toCharArray(Reader input)
  • 将输入流写入字符串
public static String toString(InputStream input)
public static String toString(InputStream input, String encoding)
public static String toString(Reader input)
  • 将输入流按行置入一个List,该方法已经实现了缓冲
public static List<String> readLines(InputStream input)
public static List<String> readLines(InputStream input, String encoding)
public static List<String> readLines(Reader input)
  • 将字符串写入输入流
public static InputStream toInputStream(String input)
public static InputStream toInputStream(String input, String encoding)
  • 将一个字节数组写出到输出流
public static void write(byte[] data, OutputStream output)
public static void write(byte[] data, Writer output)
public static void write(byte[] data, Writer output, String encoding)
  • 将一个字符数组写出到输出流
public static void write(char[] data, OutputStream output)
public static void write(char[] data, Writer output)
public static void write(char[] data, OutputStream output, String encoding)
  • 将字符串写出到输出流
public static void write(String data, OutputStream output)
public static void write(String data, Writer output)
public static void write(String data, OutputStream output, String encoding)
  • 将输出流按行置入一个Collection
public static void writeLines(Collection<?> lines, String lineEnding,OutputStream output)
public static void writeLines(Collection<?> lines, String lineEnding,OutputStream output, String encoding)
public static void writeLines(Collection<?> lines, String lineEnding,Writer writer)

代码:

List<String> lines = new ArrayList();
lines.add("hello");
lines.add("list");
lines.add("to");
lines.add("file");
OutputStream os = new FileOutputStream("D:/data.txt");
IOUtils.writeLines(lines,IOUtils.LINE_SEPARATOR,os);
  • 拷贝流
public static int copy(InputStream input, OutputStream output)
public static void copy(InputStream input, Writer output)
public static void copy(InputStream input, Writer output, String encoding)
public static int copy(Reader input, Writer output)
public static void copy(Reader input, OutputStream output)
public static void copy(Reader input, OutputStream output, String encoding)

拷贝超过2GB容量的流。

public static long copyLarge(InputStream input, OutputStream output)
public static long copyLarge(Reader input, Writer output)
  • 比较两个流是否相同
public static boolean contentEquals(InputStream input1, InputStream input2)
public static boolean contentEquals(Reader input1, Reader input2)

关闭一个IO流、socket、或者selector且不抛出异常,通常放在finally块

public static void closeQuietly(InputStream input)
public static void closeQuietly(OutputStream output)
public static void closeQuietly(Reader input)
public static void closeQuietly(Writer output)
public static void closeQuietly(Closeable closeable)
public static void closeQuietly(Socket sock)

演示下载文件

直接通过servlet实现下载的过程,其它的jsp页面等就不再演示了。

package com.xzd.test;

import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

@WebServlet("/download")
public class download extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//         这里应该是前端传递一个要下载的文件作为参数,这里直接写死
        String downFileName = "laotouhuan.png";
//       通过servletcontext对象获得读取下载文件
        ServletContext servletContext =getServletContext();
//        得到需要下载的文件类型
        String mimeType = servletContext.getMimeType( "/upload/" + downFileName);
        System.out.println("/upload/"+downFileName);
        System.out.println("mimeType====" + mimeType);
//        所以将这个告诉浏览器传递的数据是什么类型
        resp.setContentType(mimeType);
//        而上面只是告诉了浏览器接受了什么样数据 默认是页面显示,但是还需与告诉浏览器这个是要下载的
//        Content-Disposition响应头,表示收到的数据怎么处理,其值为attachment表示附件,表示下载使用,ilename= 表示指定下载的文件名也就是存在浏览器下载的地方文件名
//        中文的话需要加解密。
        if (req.getHeader("User-Agent").contains("Firefox")) {
//      针对的是火狐浏览器
            resp.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" + new BASE64Encoder().encode("老头环.png".getBytes("UTF-8")));
        } else {
//          非火狐的浏览器
            // 如果不是火狐,是IE或谷歌,使用URL编码操作

            resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("老头环.png", "UTF-8"));
        }
        InputStream resourceAsStream = servletContext.getResourceAsStream("/upload/"+ downFileName);
// 获取响应的输出流
        OutputStream outputStream = resp.getOutputStream();
        IOUtils.copy(resourceAsStream, outputStream);
    }
}

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值