Несколько потоков файлов вместо загрузки на диск, а затем ZIP? - PullRequest
0 голосов
/ 28 января 2019

У меня есть метод API, который при вызове и передаче массива файловых ключей загружает их из S3.Я хотел бы транслировать их, а не загружать на диск, а затем архивировать файлы и возвращать их клиенту.

Вот так выглядит мой текущий код:

reports.get('/xxx/:filenames ', async (req, res) => {

  var AWS = require('aws-sdk');

  var s3 = new AWS.S3();

  var str_array = filenames.split(','); 

  for (var i = 0; i < str_array.length; i++) {

  var filename = str_array[i].trim();
  localFileName = './' + filename;

  var params = { 
    Bucket: config.reportBucket,
    Key: filename
  }

      s3.getObject(params, (err, data) => {

        if (err) console.error(err)
        var file = require('fs').createWriteStream(localFileName);
        s3.getObject(params).createReadStream().pipe(file);
        console.log(file);
    })
  }
});

Как мне транслировать файлы, а не загружать их на диск, и как мне сжать их, чтобы вернуть их клиенту?

1 Ответ

0 голосов
/ 28 января 2019

Основная проблема заключается в заархивировании нескольких файлов.
В частности, загрузите их из AWS S3 оптом.
Я искал в AWS SDK и не нашел массовых операций s3.

Что приводит нас к одномуВозможное решение:

  1. Загрузка файлов один за другим и сохранение их в папке
  2. Zip-папка (с некоторыми пакетами, такими как this )
  3. Отправитьzip-папка

Это необработанный и непроверенный пример, но он может дать вам представление:

// Always import packages at the beginning of the file.
const AWS = require('aws-sdk');
const fs = require('fs');
const zipFolder = require('zip-folder');

const s3 = new AWS.S3();

reports.get('/xxx/:filenames ', async (req, res) => {

   const filesArray = filenames.split(','); 

   for (const fileName of filesArray) {
     const localFileName = './' + filename.trim();

     const params = { 
       Bucket: config.reportBucket,
       Key: filename
     }

     // Probably you'll need here some Promise logic, to handle stream operation end. 
     const fileStream = fs.createWriteStream(localFileName);
     s3.getObject(params).createReadStream().pipe(fileStream);
   }

   // After that all required files would be in some target folder.
   // Now you need to compress the folder and send it back to user.

   // We cover callback function in promise, to make code looks "sync" way.
   await new Promise(resolve => zipFolder('/path/to/the/folder', '/path/to/archive.zip', (err) => {resolve()}); 

   // And now you can send zipped folder to user (also using streams).
   fs.createReadStream('/path/to/archive.zip').pipe(res);
 });

Информация о потоках ссылка и ссылка

Внимание: Возможно, у вас могут возникнуть проблемы с асинхронным поведением, в зависимости от характера потоков, поэтому, прежде всего, проверьте, все ли файлы хранятся в папкеперед архивированием.

Просто упоминание, я не проверял этот код.Так что если появятся какие-то вопросы, давайте вместе отладим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...