客户端每次请求取大文件部分数据。
浏览器播放mp4视频时,会首先传Range消息头,检测到206状态码,和Content-Range,Accept-Ranges 会自动请求余下数据。后端需要在文件任意偏移量取数据。
参考:
springboot项目实现断点续传功能_java_脚本之家
springboot大文件上传、分片上传、断点续传、秒传的实现_java_脚本之家
springboot 大文件上传、分片上传、断点续传、秒传_getmodelrw-优快云博客
https://juejin.cn/post/7387915277318520869
在SpringBoot中实现断点续传的实例代码_java_脚本之家
主要代码:
private void videoPlayRange(String taskCode, String fileName) {
File file = getVideoFile(taskCode, fileName);
long fileLength = file.length();
String range = request.getHeader("Range");
long start = 0, end = fileLength - 1;
if (range != null) {
String[] ranges = range.replace("bytes=", "").split("-");
start = Long.parseLong(ranges[0]);
end = Math.min(fileLength - 1,start + maxPartSize*1024*1024-1);
end = ranges.length > 1 ? Long.parseLong(ranges[1]) : end;
}
// Set the content type and attachment header.
// String contentType = request.getServletContext().getMimeType(video.getFile().getAbsolutePath());
response.setContentType("video/mp4");
// response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + start + "-" + end + "/" + fileLength);
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(end - start + 1));
response.setStatus(206);
// headers.setContentType(MediaType.parseMediaType(contentType));
// Create resource that represents the part of the video file.
try (RandomAccessFile raf = new RandomAccessFile(file, "r")){
raf.seek(start);
ServletOutputStream out = response.getOutputStream();
byte[] bytes = new byte[4096];
int r = 0;
while (start<=end) {
r = raf.read(bytes,0,(int)Math.min(bytes.length,end-start+1));
if(r<=0){
break;
}
start+=r;
out.write(bytes,0,r);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}