目录
一、定义
断点续传是一种文件传输的技术和策略,用于在网络传输中出现中断或错误的情况下,能够从中断的位置继续传输文件,而无需重新传输整个文件。
二、为什么要使用断点续传
传统的文件传输方式是一次性将整个文件从发送方传输到接收方。然而,在大文件传输或不稳定的网络环境中,这种方式可能会面临一些问题。如果传输过程中出现错误或中断,例如网络中断、连接超时或其他原因,传统的方式要求重新开始传输,这会导致时间和带宽的浪费。
断点续传的作用和优势有:提高传输效率、用户体验改善、多用户上传冲突解决等。总的来说,断点续传通过分块传输和记录传输状态,提供了一种可靠、高效和用户友好的文件传输方式。
三、简单示例
在 react 框架中做以下示例,其他框架使用方法类似。
TypeScript
import React, { useState } from 'react';
const About = () => {
const [file, setFile] = useState(null);
const [progress, setProgress] = useState(0);
// 更新选择文件状态
const handleFileChange = (event: any) => {
setFile(event.target.files[0]);
};
// 触发文件上传
const handleUpload = () => {
if (file) {
uploadFile(file);
}
};
const uploadFile = (file: any) => {
// 设置每个分块的大小,这里为1MB
const chunkSize = 1024 * 1024;
// 分块的总数,使用 Math.ceil 方法向上取整。
const totalChunks = Math.ceil(file.size / chunkSize);
// 计数器,用于跟踪当前上传的分块
let currentChunk = 0;
const readFileChunk = (start: any, end: any) => {
// 获取文件的分块
const chunk = file.slice(start, end);
const formData = new FormData();
// 将这三个数据添加到表单数据中
formData.append('file', chunk);
formData.append('chunk', currentChunk.toString());
formData.append('chunks', totalChunks.toString());
// 发送分块数据到服务器
fetch('https://example.com/upload', {
method: 'POST',
body: formData,
})
.then((response) => {
if (response.ok) {
currentChunk++;
if (currentChunk < totalChunks) {
const start = currentChunk * chunkSize;
const end = start + chunkSize;
readFileChunk(start, end);
} else {
setProgress(100);
console.log('上传完成');
}
} else {
console.log('上传失败');
}
})
.catch((error) => {
console.log('上传出错', error);
});
};
readFileChunk(0, chunkSize);
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>上传</button>
<div>{progress}%</div>
</div>
)
}
export default About;
这个示例实现了一个基本的断点续传逻辑,首先定义了每个分块的大小 chunkSize 为 1MB,并创建了一个计数器 currentChunk,用于跟踪当前上传的分块。然后,将文件通过 slice() 分割成多个分块,start 和 end 分别表示分块的起始位置和结束位置。并创建了 FormData 对象,包含了传递数据的参数,通过 fetch 方法将表单数据(FormData 对象)发送到服务器的上传接口。
检查是否成功,如果成功,递增 currentChunk 计数器并检查是否还有未上传的分块。如果还有,计算下一个分块的起始位置和结束位置,并递归调用 readFileChunk 函数继续上传下一个分块;如果所有分块都上传完成,将进度设置为 100,并打印上传完成的消息。
四、前后段如何配合
断点续传的实现需要前后端配合,确保分块数据的正确上传和合并,以及断点续传的状态跟踪和恢复。
前端职责:
- 将文件分割成多个分块:前端负责将要上传的文件分割成多个较小的分块。通常使用 File.slice() 或者类似的方法来获取文件的分块数据。
- 逐个上传分块数据:前端通过网络将每个分块数据发送到后端的上传接口。可以使用 AJAX、Fetch API 或者其他网络请求库来实现。
- 保存上传进度和断点信息:前端需要记录上传的进度和已经成功上传的分块信息,以便在断点续传时能够恢复上传的状态。
后端职责:
- 提供上传接口:后端需要提供一个可以接收分块数据的上传接口,通常是一个 POST 请求的接口。
- 接收和处理分块数据:后端接收前端发送的分块数据,并将其存储在适当的位置,例如磁盘上的临时文件或者数据库中。
- 合并分块数据:当所有分块数据都上传完成后,后端需要将这些分块数据合并成完整的文件。
- 处理断点续传请求:如果上传过程中发生中断,前端会向后端发送断点续传请求,后端需要根据前端提供的断点信息,确定从哪个分块开始继续上传。
- 完成上传:在所有分块都上传完成且文件合并成功后,后端可以执行任何其他必要的操作,如保存文件信息、触发后续处理流程等。
五、总结
断点续传的关键是记录传输的状态和进度信息,以便在中断后能够准确恢复传输。通常,前端(客户端)负责将文件分割成块并发送到后端(服务器),后端接收和处理分块数据,并保存已接收的块。当传输中断时,前端可以根据已传输的块信息通知后端从中断处继续传输,而不是重新开始。它提供了一种灵活、可靠的文件传输方式,提高了传输效率和用户体验。