流文件打包下载

453 阅读1分钟

使用技术:

后端:node、egg、compressing
前端:原生js

实现流程:

后端:

  • 1、获取object-name
    let objectName = [
        ‘original/97235090537395420T001R300x300M00000235pCx2tYjlq.jpg’,
        'original/w320/h568/2923230346226924IMG_0030.mp4'
    ];
    
  • 2、创建一个临时根目录
    fs.mkdir('./a', (err) => {});
    
  • 3、根据官方文档手动封装一个getStream,官方文档
    async function getStream (objectName) {
      try {
        let result = await client.getStream(objectName);
        console.log(result);
        return result.stream;
      } catch (e) {
        console.log(e);
      }
    }
    
  • 4、因为打包必须要等.pipe()输出完,这里写了一个.pipe()监听方法
    async writeStrem(path, result) {
        return  new Promise(function (resolve, reject) {
            let writeStream = fs.createWriteStream(path);
            writeStream.on('close', function () {
                resolve(true)
            })
            result.pipe(writeStream);
        })
    }
    
  • 5、遍历object-name,流方式输出到根目录
    for(let i = 0 , len = objectName.length ; i < len ; i++){
        let result = await this.getStream(objectName[i]);
        // 截取original/后面的作为名字
        let fileName = objectName[i].substring(objectName[i].lastIndexOf("/")+1);
        // 拿到的文件下载到临时文件里
        result 
             && (result.status !== false)
             && await this.writeStrem('./a/'+ fileName, result);
         
    }
    
  • 6、此时文件已经在a文件夹里面,进行压缩
    await compressing.zip.compressDir('./a', './b.zip');
    
  • 7、删除临时文件a fs.rmdir不能删除有文件的文件夹
    let path = './a';
        // 判断文件夹是否有文件
        if( fs.existsSync(path) ) {
            // 定义名字数组
            let files = [];
            // 文件名字添加到数组
            files = fs.readdirSync(path);
            // 遍历文件名
            files.forEach((file) => {
                let curPath = path + "/" + file;
                // 删除文件
                fs.unlinkSync(curPath)
            });
            fs.rmdirSync(path);
        }
    
  • 8、设置响应头文件,输出流文件
    ctx.set("Content-Type", 'application/octet-stream');
    let strem = fs.readFileSync('./b.zip');
    ctx.body =  strem;
    

前端:

  • 1、 原生ajax请求
      let xhr = new XMLHttpRequest();
      xhr.open("post",  `/downloadFile`, true);
      xhr.responseType = 'blob';
      xhr.onload = function() {
        if (this.status == 200) {
          let blob = this.response;
          let url = window.URL.createObjectURL(blob);
          let link = document.createElement('a');
          link.style.display = 'none';
          link.href = url;
          link.setAttribute('download', 'b.zip');
          document.body.appendChild(link);
          link.click()
        } }
      xhr.setRequestHeader('Content-Type', 'application/json');
      // 传递数据
      xhr.send();