我有一个明确的端点,目前我负责处理文件上传。大文件占用大量内存b / c我正在使用bodyParser,该函数在调用处理程序函数之前将整个文件缓冲在内存中。
我从该端点上删除了bodyParser中间件,并且我在努力使用流从根本上流化文件上传-> express-> 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
,您可以看到我尝试使用已注释掉的内容,但这似乎并没有要么工作。
帮助?
答案 0 :(得分:0)
结果答案实际上很简单。我要做的就是传递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)
)
})
我发现这种情况的方式是b / c,我查看了req
对象是什么的快速源代码,并且看到它是http.IncomingMessage
对象-https://github.com/expressjs/express/blob/master/lib/request.js#L31 < / p>
然后我查看了Node文档,发现http.IncomingMessage
实现了Readable Stream接口
它实现了Readable Stream接口,以及以下内容 其他事件,方法和属性。
https://nodejs.org/docs/latest-v9.x/api/http.html#http_class_http_incomingmessage