Как определить тип данных в S3.getObject()

API node.js для S3 дает следующее описание для данных, возвращенных в обратном вызове getObject. Из http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property:

Тело - (Буфер, Типированный массив, Blob, String, ReadableStream) Данные объекта.

Это реально? Нет ли способа контролировать, что из этого происходит?

Ответ 1

Я не знаю, можете ли вы заранее контролировать тип поля data.Body, указанного в обратном вызове getObject(). Если все, что вы хотите сделать, это определить, получили ли вы буфер, вы можете попробовать Node Buffer.isBuffer (data.Body) класс метод.

В качестве альтернативы вам может понадобиться избежать проблемы вообще и использовать этот подход из документации Amazon S3:

var s3 = new AWS.S3();
var params = {Bucket: 'myBucket', Key: 'myImageFile.jpg'};
var file = require('fs').createWriteStream('/path/to/file.jpg');
s3.getObject(params).createReadStream().pipe(file);

Предполагая, что вы будете использовать этот код в типичной среде обратного вызова awsww.js async, может возникнуть смысл увидеть такой код:

var fs = require('fs');

function downloadFile(key, localPath, callback) {
  var s3 = new AWS.S3();
  var params = {Bucket: 'myBucket', Key: key};
  var file = fs.createWriteStream(localPath);

  file.on('close') {
    callback();
  }

  file.on('error', function(err) {
    callback(err);
  });

  s3.getObject(params).createReadStream().pipe(file);
}

Ответ 2

Я также не мог найти способ изменить тип тела, однако, заметив, что Body был буфером, я преобразовал буфер в ReadableStream с помощью этого удобного и довольно простого функция: AWS.util.buffer.toStream (или, возможно, вы захотите использовать другую lib, например streamifier).

Я искал что-то, где я мог бы проверять ошибки, прежде чем делать что-либо еще, в примере Amazon он переводит "создать поток записи только в случае отсутствия ошибок".

s3.getObject(params, function(err, data) {
    if (err) {
        console.log(err);
        return;
    }

    var file = require('fs').createWriteStream(name);
    var read = AWS.util.buffer.toStream(data.Body);

    read.pipe(file);
    read.on('data', function(chunk) {
        console.log('got %d bytes of data', chunk.length);
    });
});