У меня есть экспресс-конечная точка, где я в настоящее время обрабатываю загрузку файлов. Большие файлы занимают много памяти, потому что я использовал bodyParser, который буферизует весь файл в памяти перед вызовом моей функции обработчика.
Я удалил промежуточное ПО bodyParser из этой конечной точки и пытаюсь правильно использовать потоки, чтобы в основном передавать загрузку файла -> экспресс -> s3.
Это документы по методу s3, и он принимает буфер или поток.
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
маршрут
router.put('/files/:filename', putHandler({ s3Client: s3Client }))
Я попробовал это, которое передает файл в мой метод обработчика, но, похоже, он не передает его в метод s3.upload (на самом деле неудивительно)
function put ({ s3Client }) {
return (req, res) => {
...
let whenFileUploaded = new Promise((resolve, reject) => {
// const { Readable } = require('stream')
// const inStream = new Readable({
// read() {}
// })
let data = ''
req.on('data', function (chunk) {
req.log.debug('in chunk')
data += chunk
// inStream.push(chunk)
})
req.on('end', function () {
req.log.debug('in end')
})
s3Client.upload(
{
Key: filepath,
Body: data,
SSECustomerAlgorithm: 'AES256',
SSECustomerKey: sseKey.id.split('-').join('')
},
{
partSize: 16 * 1024 * 1024, // 16mb
queuSize: 1
},
(err, data) => err ? reject(err) : resolve(data)
)
})
Я предполагаю, что мне нужно создать поток и подключить req.on('data... к моему потоку, а затем установить Body: inStream, что, как вы можете видеть, я пытался сделать с закомментированным материалом, но это тоже не сработало.
Помощь?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Оказывается, ответ на самом деле очень прост. Все, что мне нужно было сделать, это передать объект req.
function put ({ s3Client }) {
return (req, res) => {
...
let whenFileUploaded = new Promise((resolve, reject) => {
s3Client.upload(
{
Key: filepath,
Body: req, // <-- NOTE THIS LINE
SSECustomerAlgorithm: 'AES256',
SSECustomerKey: sseKey.id.split('-').join('')
},
{
partSize: 16 * 1024 * 1024, // 16mb
queuSize: 1
},
(err, data) => err ? reject(err) : resolve(data)
)
})
Я выяснил это следующим образом: я посмотрел исходный код экспресса, что такое объект req, и увидел, что это объект http.IncomingMessage - https://github.com/expressjs/express/blob/master/lib/request.js#L31
Затем я посмотрел документы Node и увидел, что http.IncomingMessage реализует интерфейс Readable Stream.
It implements the Readable Stream interface, as well as the following additional events, methods, and properties.
https://nodejs.org/docs/latest-v9.x/api/http.html#http_class_http_incomingmessage