说明:
在下载时,将下载任务人为的划分为几个部分,碰到网络故障断开时,可以从已经下载的部分开始继续下载未完成的部分,而没有必要从头开始下载。用户可以节省时间,提高速度。
实现方案:
通过springboot实现断点续传
@GetMapping(value = "/downloadFile")
public ResponseEntity<Resource> downloadFile(@RequestHeader(value = "Range", required = false) String range,String filePath) {
File file = new File(filePath);
if (file.exists() && file.isFile()) {
HttpHeaders headers = new HttpHeaders();
long fileLength = file.length();
// 处理断点续传的 Range 请求头
if (range!= null) {
String[] rangeValues = range.split("=")[1].split("-");
long startByte = Long.parseLong(rangeValues[0]);
long endByte;
if (rangeValues.length > 1) {
endByte = Long.parseLong(rangeValues[1]);
} else {
endByte = fileLength - 1;
}
headers.set(HttpHeaders.CONTENT_RANGE, "bytes " + startByte + "-" + endByte + "/" + fileLength);
headers.set(HttpHeaders.CONTENT_LENGTH, String.valueOf(endByte - startByte + 1));
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
randomAccessFile.seek(startByte);
byte[] data = new byte[(int) (endByte - startByte + 1)];
randomAccessFile.readFully(data);
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.headers(headers)
.body(new ByteArrayResource(data));
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
} else {
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=utf-8''" + URLEncoder.encode("下载.zip", "UTF-8"));
return ResponseEntity.ok()
.headers(headers)
.contentLength(fileLength)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new FileSystemResource(file));
}
} else {
return ResponseEntity.notFound().build();
}
}
如果是通过nginx代理的话,可以通过nginx配置实现断点续传
以下是实现分片下载的基本配置步骤:
- 1. 确保你已经安装并配置好了 NGINX 服务器。
- 2. 编辑 NGINX 配置文件:
- 通常,NGINX 的配置文件位于 `/etc/nginx/nginx.conf` 或 `/etc/nginx/conf.d/default.conf`。打开配置文件并找到你想要启用分片下载的 `server` 或 `location` 块。
- 3. 配置 `location` 块:
- 在 `location` 块中,添加以下指令来启用断点续传功能:
server {
listen 80;
server_name your_server_name;
location /downloads/ {
root /path/to/your/files;
# 允许分片下载
aio on;
# 允许断点续传
output_buffers 1 512k;
# 启用高效文件传输
sendfile on;
# 允许客户端指定下载范围
tcp_nopush on;
tcp_nodelay on;
# 设置缓存控制头
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
}
- 4. 编辑并保存配置文件后,重新加载 NGINX 配置以使更改生效
sudo nginx -s reload
前端实现:
前端发送的 Range
请求头的格式通常为 Range: bytes=startByte-endByte
,其中 startByte
表示起始字节位置,endByte
表示结束字节位置。如果只指定起始字节位置,例如 Range: bytes=500-
,表示从第 500 个字节开始到文件末尾。