繁体   English   中英

通过Express服务器将文件流传输到s3

[英]Stream file upload to s3 via express server

我有一个明确的端点,目前正在处理文件上传。 大文件占用大量内存b / ci使用的是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 ,你可以看到我尝试了注释掉的东西,但这似乎没有用无论是。

救命?

原来答案实际上很简单。 我要做的就是传递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对象http.IncomingMessage : //github.com/expressjs/express/blob/master /lib/request.js#L31

然后,我查看了Node文档,发现http.IncomingMessage实现了Readable Stream接口。

它实现了Readable Stream接口以及以下其他事件,方法和属性。

https://nodejs.org/docs/latest-v9.x/api/http.html#http_class_http_incomingmessage

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM