美文网首页
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