如何从服务器获取图像文件并将其压缩到sailsjs [英] How to fetch the image files from a server and zip it in sailsjs

查看:65
本文介绍了如何从服务器获取图像文件并将其压缩到sailsjs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 s3 url 压缩所有图像.我是在sailsjs框架的服务器端做的.

I want to zip all the images from s3 urls. I am doing it on server side on sailsjs framework.

我尝试使用 axios 下载图像并使用zipdir".图像正在临时文件夹中下载.但它没有被正确压缩.

I tried using axios to download the images and used 'zipdir'. The images are getting downloaded in temp folder. But its not getting zipped properly.

this.downloadFiles = function (req, res) {
    var resObj = {}
    async.waterfall([
        this.createFolder.bind(undefined, req),
        this.downloadFilesAxios.bind(undefined, req),
        this.zipTheFiles.bind(undefined, req)
    ], function final(err, result) {
        if (err) {
            console.log('SOME ERROR', err);
            resObj.statusCode = err.statusCode || 500;
        } else {
            resObj.statusCode = 200;
            resObj.result = result.questionList;
        }
        console.log('------', resObj.statusCode)
        resObj.messageKey = sails.config.statusCode[resObj.statusCode].key;
        resObj.message = sails.config.statusCode[resObj.statusCode].message;
        return res.send(resObj);
    });
};



}

this.downloadFilesAxios = function (req, obj, callback) {
    SurveyDocs.find({ surveyId: req.body.surveyId })
        .exec(function (err, docsDetails) {
            async.map(docsDetails, function (img, cb) {
                const url = img.docS3Url;

                let imageName = img.docFileName;
                const path = Path.resolve(__dirname, "temp", imageName);
                const writer = Fs.createWriteStream(path)

                Axios({
                    method: 'get',
                    url: url,
                    responseType: 'stream'
                })
                    .then(function (response) {
                        response.data.pipe(writer)
                    })
                writer.on('finish', (done) => {
                    console.log('success!!!');
                    cb(null, null)
                });
                writer.on('error', (err) => {
                    console.log('failed!!!');
                    cb(err, null)
                });

            }, (err, data) => {
                if (err) {
                    console.log('errrr', err);
                }
                callback(null, obj);
            });
        })
};

this.zipTheFiles = function (req, obj, callback) {
    var surveyId = req.body.surveyId;
    var tempDir = 'assets/zip/' + surveyId + '.zip'
    zipdir('temp', { saveTo: tempDir }, function (err, buffer) {
        callback(null, obj);
    });
    callback(null, obj);
}

这里我得到一个损坏的 zip 文件.请提出解决方案.

Here I am getting a corrupt zip file. Please suggest the solution.

推荐答案

我尝试了您的示例,您需要考虑一些事项才能使其正常工作.

I tried out your example there are a few things you need to consider in order to make it work.

const async = require('async');
const fs = require('fs');
const path = require('path');
const zipDir = require('zip-dir');
const axios = require('axios');
let writer;


async.waterfall([
  createFolder,
    downLoadFileAxios,
    zip

], function (err, result) {
  if (err) {
    console.log(err);
  } else {
    console.log('result :', result);
  }
});

假设此方法创建了 temp 文件夹

let's assume this method creates the temp folder

function createFolder(callback) {
  setTimeout(function() {
    callback(null, 'temp');
  }, 1000);
}

这里的 writeStream 对象及其事件应该放在 then 块中.以便它正确地将流写入文件.

Here the writeStream object and it's events should be put inside the then block. So that it writes the stream to the file correctly.

这里的另一件重要的事情是你没有在承诺中附加一个导管块,所以如果发生任何异常,它只会被吃掉.

Another important thing here is you are not having a cath block attached the promise, so if any exception occurs it will be simply eaten up.

function downLoadFileAxios(dirPath, callback) {
  // Hard coded the images url for the sake of simplicity
  let files = [
    'https://free-images.com/lg/be5e/climbing_helmets_climbing_equipment.jpg',
    'https://free-images.com/lg/87ce/lilac_lilac_bush_lilac.jpg'
  ];

  async.mapSeries(files, function(img, cb) {
    let name = img.slice(img.lastIndexOf('/') + 1);
    let imagePath = path.resolve(__dirname, "newDir", name);
    writer = fs.createWriteStream(imagePath);
    axios({
      method: 'get',
      url: img,
      responseType: 'stream'
    }).
    then(function(response) {
      response.data.pipe(writer);
      writer.on('finish', (done) => {
        console.log('success!!!');
          cb(null, null)
      });
      writer.on('error', (err) => {
          console.log('failed!!!');
          cb(err, null)
      });
    })
    .catch((err) => {
      console.log(err);
    })
  }, function(err, result) {
    if (err) {
      console.log('errrr', err);
    }
    callback(null, 'done downloading');
  })

}


function zip (dirPath, callback) {
  let zipPath = path.resolve(__dirname, "assets", "file.zip");
  // console.log(`got directory path : ${dirPath}`);

  zipDir("newDir", {
    saveTo: zipPath
  }, function(err, buffer) {
      if(err) {
        callback(err, null);
      } else {
        callback(null, 'done');
      }
  });
}

这可以使用 Async/Await 轻松完成,如下所示.

This can be easily done using Async/Await like following.

const async = require('async');
const fs = require('fs');
const path = require('path');
const zipDir = require('zip-dir');
const axios = require('axios');
var writer;

// faking the directory creation part
async function createFolder(callback) {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(true);
  }, 2000);
 });
}

//Executes in the specified order.
(async () => {
  await createFolder();
  await downLoadFile();
  await zipTheFile();
})();

async function downLoadFile() {

  let files = [
    'https://free-images.com/lg/be5e/climbing_helmets_climbing_equipment.jpg',
    'https://free-images.com/lg/87ce/lilac_lilac_bush_lilac.jpg'
  ];

  for(let i= 0; i<files.length; i++) {
    await downLoadFileAxios(files[i]);
  }
}

async function downLoadFileAxios(url) {
  let name = url.slice(url.lastIndexOf('/') + 1);
  let imagePath = path.resolve(__dirname, "newDir", name);
  let writer = fs.createWriteStream(imagePath);

  const response = await axios({
    url,
    method: 'GET',
    responseType: 'stream'
  })

  response.data.pipe(writer)

  return new Promise((resolve, reject) => {
    writer.on('finish', resolve)
    writer.on('error', reject)
  })
}

function zipTheFile () {
  let zipPath = path.resolve(__dirname, "assets", "file.zip");
  return new Promise((resolve, reject) => {
    zipDir("newDir", {
      saveTo: zipPath
    }, function(err, buffer) {
        if(err) {
          return reject(err);
        }
        return resolve('done');
    });
  })
}

希望这会有所帮助!

这篇关于如何从服务器获取图像文件并将其压缩到sailsjs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆