美文网首页
SpringBoot 文件下载、分片下载

SpringBoot 文件下载、分片下载

作者: _年少 | 来源:发表于2019-08-18 01:16 被阅读0次

普通下载功能的实现

    FileInputStream inputStream = null;
    ServletOutputStream os = null;
    try {
        inputStream = new FileInputStream(file);

        //设置响应状态200
        response.setStatus(HttpServletResponse.SC_OK);
        //设置内容类型
        response.setContentType(getContentType(fileId));
        //添加响应头 设置内容长度
        response.addHeader("Content-Length", String.valueOf(file.length()));
        //添加响应头 设置允许浏览器可尝试恢复中断的下载
        response.addHeader("Accept-Ranges", "bytes");
        response.addHeader("Cache-control", "private");
        //添加响应头 设置浏览器另存为对话框的默认文件名
        response.addHeader("Content-Disposition", "filename=" + file.getName());
        response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");

        os = response.getOutputStream();

        byte[] buf = new byte[1024];
        int len;
        while ((len = inputStream.read(buf)) != -1) {
            os.write(buf, 0, len);
            os.flush();
        }
    } catch (Exception e) {
        //操作文件失败时返回响应状态 500
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    } finally {
        //结束后释放资源
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

支持分片下载功能的实现

  • 这里是因为测试中ios safari 浏览器无法正常打开播放视频文件,通过抓取分析浏览器访问静态资源视频过程实现的代码
    //获取请求头
    String range = request.getHeader("range");
    String referer = request.getHeader("referer");
    //处理range 计算请求的哪部分数据
    String[] split = range.split("bytes=|-");
    long begin = 0;
    if (split.length >= 2) {
        begin = Long.valueOf(split[1]);
    }
    long end = file.length() - 1;
    if (split.length >= 3) {
        end = Long.valueOf(split[2]);
    }
    long len = (end - begin) + 1;
    //如果请求的文件长度超过文件实际长度 返回错误状态
    if (end > file.length()) {
        //返回状态 500
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }

    FileInputStream inputStream = null;
    ServletOutputStream os = null;
    try {
        //创建文件流
        inputStream = new FileInputStream(file);
        //将指针移到请求片段的开始位置
        inputStream.skip(begin);
        //设置响应状态 206 部分内容
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        //设置内容类型
        response.setContentType(getContentType(fileId));
        //添加响应头 设置片段开始位置 结束位置 文件总长度
        response.addHeader("Content-Range", "bytes " + begin + "-" + end + "/" + file.length());
        //添加响应头 设置响应片段的长度
        response.addHeader("Content-Length", String.valueOf(len));
        //添加响应头 设置允许浏览器可尝试恢复中断的下载
        response.addHeader("Accept-Ranges", "bytes");
        response.addHeader("Cache-control", "private");
        //添加响应头 设置浏览器另存为对话框的默认文件名
        response.addHeader("Content-Disposition", "filename=" + file.getName());
        response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");

        os = response.getOutputStream();
        //从文件流中读指定长度的片段输出
        byte[] buf = new byte[1024];
        while (len > 0) {
            inputStream.read(buf);
            long l = len > 1024 ? 1024 : len;
            os.write(buf, 0, (int) l);
            os.flush();
            len -= l;
        }
    } catch (Exception e) {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    } finally {
        //释放资源
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Github

相关文章

网友评论

      本文标题:SpringBoot 文件下载、分片下载

      本文链接:https://www.haomeiwen.com/subject/myulsctx.html