Если я правильно понимаю, вы хотите получить объект из корзины s3 и передать его в свой HTTP-ответ в виде потока.
Вместо того, чтобы получать данные в буферах, а потом искать способпреобразование его в поток может быть сложным и имеет свои ограничения: если вы действительно хотите использовать мощь потоков, не пытайтесь преобразовать его в буфер и загрузить весь объект в память, вы можете создать запрос, который передает возвращаемый потокданные напрямую в объект потока Node.js путем вызова метода createReadStream по запросу.
Вызов createReadStream возвращает необработанный поток HTTP, управляемый запросом.Затем поток необработанных данных может быть передан в любой объект потока Node.js.
Этот метод полезен для вызовов служб, которые возвращают необработанные данные в своей полезной нагрузке, таких как вызов getObject объекта службы Amazon S3 для потоковой передачи данных.непосредственно в файл, как показано в этом примере.
//I Imagine you have something similar.
server.get ('/image', (req, res) => {
let s3 = new AWS.S3({apiVersion: '2006-03-01'});
let params = {Bucket: 'myBucket', Key: 'myImageFile.jpg'};
let readStream= s3.getObject(params).createReadStream();
// When the stream is done being read, end the response
readStream.on('close', () => {
res.end()
})
readStream.pipe(res);
});
При потоковой передаче данных из запроса с использованием createReadStream возвращаются только необработанные данные HTTP.SDK не выполняет постобработку данных, эти необработанные HTTP-данные могут быть возвращены напрямую.
Примечание: Поскольку Node.js не может перемотать большинство потоков, если запрос первоначально выполняется успешно,тогда логика повтора отключена для остальной части ответа.В случае сбоя сокета во время потоковой передачи SDK не будет пытаться повторить попытку или отправить дополнительные данные в поток.Логика вашего приложения должна выявлять такие потоковые сбои и обрабатывать их.
Правки: После правок исходного вопроса я вижу, что s3 отправляет объект потока PassThrough, который отличается отFileStream в Nodejs.Поэтому, чтобы обойти проблему, используйте память (если ваши файлы не очень большие и у вас достаточно памяти).
Используйте пакет memfs
, он заменит собственный fs
в вашем приложении https://www.npmjs.com/package/memfs
Установите пакет по npm install memfs
и потребуйте следующее:
const {fs} = require('memfs');
и ваш код будет выглядеть как
static async downloadFile(Bucket, Key) {
const result = await s3
.getObject({
Bucket,
Key
})
.promise();
fs.writeFileSync(`/${Key}`,result.Body);
const file = await fs.createReadStream(`/${Key}`);
return file;
}
Обратите внимание, что единственное изменение, которое яЯ сделал в ваших функциях то, что я изменил путь ${Path.basename(Key)}
на /${Key}
, потому что теперь вам не нужно знать путь к вашей исходной файловой системе, мы храним файлы в памяти.Я проверил, и это решение работает