大文件下载——断点续传

package com.zxz.study.util;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class DownloadUtil {

    public static void download(File file, HttpServletRequest request, HttpServletResponse response) {
        download(file, "", request, response);
    }

    /**
     * 支持断点续传的下载文件
     * @param file 文件
     * @param fileName 下载名称
     * @param request
     * @param response
     */
    public static void download(File file, String fileName, HttpServletRequest request, HttpServletResponse response) {
        if (fileName == null || "".equals(fileName)) {
            fileName = file.getName();
        }
        long length = file.length();
        // 1.解析Range参数
        String range = request.getHeader("Range");
        System.out.println("range==> "+range);

        Map<String, Long> map = getFromAndTo(range);
        Long from = map.get("from");
        Long to = map.get("to");
        if (from == null) {
            from = 0L;
        }
        if (to == null) {
            to = length - 1;
        }
        // 2.设置返回的状态值(200:全部处理,206:部分处理)
        if (from == 0 && to == length - 1) {
            response.setStatus(200);
        } else {
            response.setStatus(206);
        }
        // 3.设置响应头
        response.setHeader("Accept-Ranges", "bytes");
        String contentRange = "bytes="+from+"-"+to+"/"+length;
        response.setHeader("Content-Range", contentRange);
        // 4.设置编码格式
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream;charset=GBK");
        // 5.设置文件下载名需要编码ISO-8859-1
        try {
            fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        // 6.输出流
        ServletOutputStream outputStream = null;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            outputStream = response.getOutputStream();
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            if (from > 0) {
                bis.skip(from);
            }
            byte[] buffer = new byte[100 * 1024];
            int len = 0;
            while ((len = bis.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
        } catch (IOException e) {
            // e.printStackTrace();
        } finally {
            try {
                bis.close();
            } catch (IOException e) {
                // e.printStackTrace();
            }
            try {
                fis.close();
            } catch (IOException e) {
                // e.printStackTrace();
            }
        }
    }

    /**
     * 解析断点续传的 Range参数
     * @param range Range参数
     * @return map (key值"from", "to")
     */
    private static Map<String, Long> getFromAndTo(String range) {
        Map<String, Long> map = new HashMap<>();
        map.put("from", null);
        map.put("to", null);
        if (range != null) {
            String[] array = range.split("=|-");
            if (array.length >= 2) {
                String from = array[1].trim();
                if (!from.isEmpty()) {
                    map.put("from", Long.parseLong(from));
                }
                if (array.length >= 3) {
                    String to = array[2].trim();
                    if (!to.isEmpty()) {
                        map.put("to", Long.parseLong(to));
                    }
                }
            }
        }
        return map;
    }
}

 

posted @ 2021-01-27 12:31  一柒微笑  阅读(252)  评论(0编辑  收藏  举报