欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 大文件切片上传和断点续传

大文件切片上传和断点续传

2025/3/29 19:06:03 来源:https://blog.csdn.net/wscfan/article/details/146515743  浏览:    关键词:大文件切片上传和断点续传

大文件切片上传和断点续传

一、技术原理

  1. 文件切片上传

    • 将大文件按固定大小(如5MB)分割为多个切片(Blob对象的slice()方法实现)。
    • 通过文件内容的哈希值(如MD5)生成唯一标识,用于服务端校验文件完整性。
    • 切片上传支持并行传输和失败重试,减少单次请求压力。
  2. 断点续传

    • 客户端记录已上传的切片索引(如通过localStorage),上传前与服务端校验未上传的切片。
    • 服务端需保存切片的上传状态(如Redis记录哈希值或文件分片状态)。

二、前端实现步骤

1. 文件切片与哈希计算
// 切片函数(以50KB为例)
function splitFile(file, chunkSize = 1024 * 50) {const chunks = [];let cur = 0;while (cur < file.size) {chunks.push(file.slice(cur, cur + chunkSize));cur += chunkSize;}return chunks;
}// 计算文件哈希(使用SparkMD5)
async function calculateHash(chunks) {const spark = new SparkMD5.ArrayBuffer();for (const chunk of chunks) {const buffer = await chunk.arrayBuffer();spark.append(buffer);}return spark.end(); // 生成唯一哈希值
}

优化:使用Web Worker避免哈希计算阻塞主线程。

2. 断点续传逻辑
// 检查已上传切片(示例为React)
const checkUploadedChunks = async (fileName, totalChunks) => {const res = await axios.get('/check-upload', { params: { fileName } });return res.data.uploadedIndexes; // 服务端返回已上传的切片索引
};// 上传逻辑(支持续传)
const uploadFile = async (file) => {const chunks = splitFile(file);const hash = await calculateHash(chunks);const uploaded = await checkUploadedChunks(hash);for (let i = 0; i < chunks.length; i++) {if (uploaded.includes(i)) continue; // 跳过已上传的切片const formData = new FormData();formData.append('file', chunks[i]);formData.append('hash', hash);formData.append('index', i);await axios.post('/upload', formData);localStorage.setItem(hash, JSON.stringify([...uploaded, i])); // 记录进度}await axios.post('/merge', { hash }); // 通知服务端合并切片
};

三、后端处理要点

  1. 切片接收与存储

    • 使用Node.js的multer中间件接收切片,按哈希值分目录存储。
    • 示例代码:
    app.post('/upload', upload.single('file'), (req, res) => {const { hash, index } = req.body;const chunkPath = `./uploads/${hash}/${index}`;fs.writeFileSync(chunkPath, req.file.buffer); // 保存切片res.send({ success: true });
    });
    
  2. 合并切片

    • 按索引顺序读取切片文件,合并为完整文件:
    app.post('/merge', (req, res) => {const { hash } = req.body;const chunks = fs.readdirSync(`./uploads/${hash}`);chunks.sort((a, b) => a - b);const mergedFile = chunks.map(chunk => fs.readFileSync(`./uploads/${hash}/${chunk}`));fs.writeFileSync(`./uploads/${hash}.mp4`, Buffer.concat(mergedFile));res.send({ success: true });
    });
    

四、优化策略

  1. 秒传
    • 服务端在接收哈希值后,若文件已存在,直接返回成功。
  2. 并行上传
    • 使用Promise.all同时上传多个切片(需控制并发数)。
  3. 进度显示
    • 通过已上传切片数与总数计算进度百分比,更新UI。
  4. 错误重试
    • 为每个切片设置重试机制(如3次重试上限)。

总结

通过切片上传和断点续传技术,可显著提升大文件上传的稳定性及用户体验。关键点包括文件哈希生成、分片状态管理、服务端合并逻辑及错误处理。实际开发中需根据场景优化参数(如切片大小、并发数)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词