代码之家  ›  专栏  ›  技术社区  ›  Catfish

流文件通过express服务器上传到s3

  •  0
  • Catfish  · 技术社区  · 6 年前

    我有一个express端点,在这里我当前处理文件上传。大文件占用了大量的内存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 回复  |  直到 6 年前
        1
  •  1
  •   Catfish    6 年前

    原来答案其实很简单。我所要做的就是通过 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我查看了express源代码 需求 对象是,我看到它是 http.IncomingMessage 对象- https://github.com/expressjs/express/blob/master/lib/request.js#L31

    然后我查看了节点文档 http.IncomingMessage消息 实现可读流接口

    它实现了可读流接口,以及 其他事件、方法和属性。

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