当前位置: 首页 > news >正文

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

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

一、技术原理

  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次重试上限)。

总结

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

相关文章:

  • Typora1.10破解教程
  • 数智读书笔记系列024《主数据驱动的数据治理 —— 原理、技术与实践》
  • SSM整合
  • MySQL MVCC的快照读和当前读区别,Redis的RDB+AOF混合持久化流程。
  • 用SVG绕过浏览器XSS审计
  • Axure项目实战:智慧城市APP(五)新闻资讯、就业信息(动态面板)
  • 微调0.5 B-32B模型要达到85%的准确率需要的数据和资源-会话质检和会话小结
  • 比手动备份快 Iperius全自动加密备份,NAS/云盘/磁带机全兼容
  • MagicFlow-防火墙网关-任意文件读取漏洞
  • 如何面对自己有意识和无意识的逃避(一)
  • c++R 格式
  • 超融合服务器是什么
  • python中使用openssl构建root证书,CSR,并验证
  • Go 语言 fmt 模块的完整方法详解及示例
  • 标星 62.9 万,8 个 yyds 的 GitHub 开源项目 !
  • C++中的std::move函数详解:移动语义与资源管理
  • golang结构体与指针类型
  • ARM day2
  • protobuf为什么快
  • 基于ssm的微博网站(全套)
  • 首次带人形机器人走科技节红毯,傅利叶顾捷:没太多包袱,很多事都能从零开始
  • 贞丰古城:新垣旧梦间的商脉与烟火
  • 六省会共建交通枢纽集群,中部六省离经济“第五极”有多远?
  • 占地57亩的“潮汕豪宅”面临强制拆除:曾被实施没收,8年间举行5次听证会
  • 从能源装备向应急装备蓝海拓展,川润股份发布智能综合防灾应急仓
  • 被前男友泼汽油致残后,一个女孩经历的双重灼烧