美文网首页
nodejs 切片断点续传

nodejs 切片断点续传

作者: 芸芸众生ing | 来源:发表于2021-04-13 17:16 被阅读0次

    nodejs服务端 body解析用的是 const formidableMiddleware = require("express-formidable");

    /**
     * 切片上传
     *
     */
    const PATH = require("path");
    const FS = require("fs");
    const mkDir = require("./ApiMkDir"); // 创建目录的封装方法
    
    module.exports = function (req, res, config) {
      return new Promise((resolve, reject) => {
        // 获取时间
        // 生成储存目录名称
        let date = new Date();
        let path = `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}`;
        // 文件目录
        let savePath = PATH.resolve(config.root, "assets/" + path);
        let cachePath = PATH.resolve(config.root, "cacheUploads");
        // 判断目录是否存在,不存在创建目录
        if (!FS.existsSync(savePath)) mkDir(savePath);
        if (!FS.existsSync(cachePath)) mkDir(cachePath);
        // 获取分片数据
        let { index, total, md5 } = req.fields;
        // 临时文件路径
        let TmpFileName = cachePath + "/" + req.files["file"].name;
        // 存储文件路径
        let FileName = savePath + "/" + req.files["file"].name;
        // 当前文件传输进度管理
        let TmpFileNameMange = cachePath + "/" + req.files["file"].name + ".txt";
        TmpFileName = PATH.normalize(TmpFileName);
        TmpFileNameMange = PATH.normalize(TmpFileNameMange);
        FileName = PATH.normalize(FileName);
        // 是否第一次传输
        if (FS.existsSync(FileName)) FS.unlinkSync(FileName);
        if (FS.existsSync(TmpFileNameMange)) {
          let test = FS.readFileSync(TmpFileNameMange, { encoding: "utf-8" });
          if (test) {
            let { i, md5: md } = JSON.parse(test);
            if (md === md5 && Number(i) > Number(index)) {
              resolve(i);
              return;
            }
          }
        }
        // 获取上传的文件buffer
        let buffer = FS.readFileSync(req.files["file"].path);
        // 写入临时文件
        if (FS.appendFileSync(TmpFileName, buffer)) reject();
        // 传输完成,移动到保存目录
        // 写入保存文件
        FS.writeFileSync(
          TmpFileNameMange,
          JSON.stringify({ i: index, total, md5 })
        );
        if (index === total) {
          FS.renameSync(TmpFileName, FileName);
          FS.unlinkSync(TmpFileNameMange);
          resolve();
          return;
        }
        resolve(index);
      });
    };
    

    前端js代码

     async submit() {
          let file = this.$refs.file.files[0];
          this.upload(file);
        },
        async upload(file, index = 0) {
          // 获取文件大小
          let fileSize = file.size;
          // 每个块的大小
          let chunkSize = 1024 * 1024 * 0.0005;
          // 共多少块
          let chunkNum = Math.ceil(fileSize / chunkSize);
          // 定义formData对象
          let formData = new FormData();
          // 定义结束位置;
          let end = index + 1;
          // 片段是否最后一片,如果不是最后一片,那么就是每片的位置
          if (end < chunkNum) end = end * chunkSize;
          // 如果是最后一片,结束位置等于文件最后的位置
          else end = fileSize;
          // 获取单个切片
          let chunData = file.slice(index * chunkSize, end);
          // 储存单个切片
          formData.append("file", chunData, file.name);
          formData.append("index", index + 1); //第几片
          formData.append("total", chunkNum); //第几片
          formData.append('md5',md5(file))
          let { data } = await axios({
            url: "http://127.0.0.1:3000/api/chunkUpload",
            method: "post",
            data: formData,
            headers: { token: "token" }
          });
          // 后台需要返回当前切片位置
          index = data.data - 0; 
          if (end < fileSize) this.upload(file, index);
        }

    相关文章

      网友评论

          本文标题:nodejs 切片断点续传

          本文链接:https://www.haomeiwen.com/subject/treclltx.html