likes
comments
collection
share

大文件分段上传断点存续,MD5,跨端技术,哪里的上传都是一样的

作者站长头像
站长
· 阅读数 60

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…

前言

文件上传刚开始感觉好麻烦,还有续存断点,还有检查文件是否上传过,不必重复上传,而且框架的一些上传组件跟公司自己用到逻辑也不一样。所以还是废了一点事儿的,那么就好好了解下文件上传

安装

npm i spark-md5

页面中引用

import SparkMD5 from 'spark-md5'

具体使用方法

支持异步调用fileMd5(file).then((res)=>console.log(res)),返回md5和文件大小

import SparkMD5 from "spark-md5";

export default function fileMd5(file) {
  return new Promise(resolve => {
    // 创建md5对象
    const spark = new SparkMD5.ArrayBuffer();
    // 读取文件内容
    const fileReader = new FileReader();
    // 文件加载
    fileReader.onload = function(e) {
     // 添加buffer数组
      spark.append(e.target.result); 
      const md5 = spark.end();
      resolve({
          md5,
          size: file.size
        });
    }
    fileReader.onerror = function() {
      console.warn("fileReader.onerror is error");
    };
  });
}

但是当文件特别大的时候就需要断点存续了,分段上传,上传大文件时,将大文件分解为一段一段的,然后上传至服务器,服务器将所有分解的文件组合成最初的大文件,实现大文件上传。

我们公司上传逻辑是这样的

  • fileCheck:先检查文件是否上传过,上传过就直接返回文件地址,不用再重复上传了
  • fileChunkCheck:没有上传过,检查文件的片段有没有上传过,避免重复上传浪费资源浪费时间
  • fileChunkUpload:层层检查,这步才开始真正的上传。
import SparkMD5 from "spark-md5";

export default function chunkFileMd5(file) {
  return new Promise(resolve => {
    /**
     * 生成MD5
     */
    const dataArr = [];
    const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
    //分段的大小 5MB
    const chunkSize = 1048576 * 5;
    // 计算多少段
    const chunks = Math.ceil(file.size / chunkSize);
    let currentChunk = 0;
    const sparkAll = new SparkMD5.ArrayBuffer();
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();
    fileReader.onload = function(e) {
      // 添加数组buffer
      spark.append(e.target.result); 
      // 添加数组buffer
      sparkAll.append(e.target.result);
      currentChunk++;
      const md5 = spark.end();
      dataArr.push({
      //分段下标
        currentChunk,
        //分段总数
        chunks,
        md5,
        blob,
        size: ((start + chunkSize) >= file.size) ? (file.size % chunkSize) : chunkSize
      });
      //判断是否结束
      if (currentChunk < chunks) {
      //进行下一段
        loadNext();
      } else {
      //总的结束
        const md5 = sparkAll.end();
        //返回结果
        resolve({
          md5,
          size: file.size,
          //分段数组
          dataArr,
          chunkSize
        });
      }
    };

    fileReader.onerror = function() {
      console.warn("fileReader.onerror is error");
    };
    //分段开始
    var start = null;
    //分段结束
    var end = null;
    //分段文件
    var blob = null;
    function loadNext() {
      start = currentChunk * chunkSize;
      end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
      blob = blobSlice.call(file, start, end);
      //读取分段文件
      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
    }
    //默认开始
    loadNext();
  });
}

总结

这两个方法我一直在用,pc端的上传,小程序的上传,移动端的上传直接复制过去就好了。MD5是一种加密工具,但是在文件上传这里,我理解成文件的id,像这样检查文件是否上传过,直接传这个id就好了,方便很多也不会出错。

这次内容就总结到这里。我的文章都是学习过程中的总结,共同进步学习,如果发现错误,也欢迎留言指出,我及时更正。

转载自:https://juejin.cn/post/7103799605623521294
评论
请登录