【问题标题】:Stream file upload to s3 via express server通过快速服务器将流文件上传到 s3
【发布时间】:2019-03-05 03:30:57
【问题描述】:

我有一个快速端点,我目前在其中处理文件上传。大文件占用大量内存 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,您可以看到我尝试使用注释掉的东西,但这似乎也不起作用。

帮助?

【问题讨论】:

    标签: javascript node.js express amazon-s3


    【解决方案1】:

    原来答案其实很简单。我所要做的就是传递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 对象是什么的 express 源代码,我发现它是一个 http.IncomingMessage 对象 - https://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

    【讨论】:

    • 您能否详细说明如何上传到此代码?它是一种形式吗?用身体发布方法?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2020-09-22
    • 2021-11-07
    相关资源
    最近更新 更多