Javascript AWS SDK S3上传方法,Body流生成空文件

osm*_*tes 10 upload stream amazon-s3 node.js

我试图使用的方法上传S3使用ReadableStream从模块fs.

文件说,一个ReadableStream可以使用BodyPARAM:

Body - (Buffer,Typed Array,Blob,String,ReadableStream)对象数据.

另外,上载方法的描述是:

如果有效负载足够大,则使用智能并发处理部件来上传任意大小的缓冲区,blob或流.

此外,这里:使用nodejs aws sdk生成的pdf上传到AWS S3,@ shivendra说他可以使用ReadableStream并且它可以工作.

这是我的代码:

const fs = require('fs')
const S3 = require('aws-sdk/clients/s3')

const s3 = new S3()

const send = async () => {
  const rs = fs.createReadStream('/home/osman/Downloads/input.txt')
  rs.on('open', () => {
    console.log('OPEN')
  })
  rs.on('end', () => {
    console.log('END')
  })
  rs.on('close', () => {
    console.log('CLOSE')
  })
  rs.on('data', (chunk) => {
    console.log('DATA: ', chunk)
  })

  console.log('START UPLOAD')

  const response = await s3.upload({
    Bucket: 'test-bucket',
    Key: 'output.txt',
    Body: rs,
  }).promise()

  console.log('response:')
  console.log(response)
}

send().catch(err => { console.log(err) })
Run Code Online (Sandbox Code Playgroud)

它得到了这个输出:

START UPLOAD
OPEN
DATA: <Buffer 73 6f 6d 65 74 68 69 6e 67>
END
CLOSE
response:
{ ETag: '"d41d8cd98f00b204e9800998ecf8427e"',
  Location: 'https://test-bucket.s3.amazonaws.com/output.txt',
  key: 'output.txt',
  Key: 'output.txt',
  Bucket: 'test-bucket' }
Run Code Online (Sandbox Code Playgroud)

问题是我在S3(output.txt)生成的文件有0字节.

有人知道我做错了什么?

如果我通过缓冲区就Body可以了.

Body: Buffer.alloc(8 * 1024 * 1024, 'something'), 
Run Code Online (Sandbox Code Playgroud)

但这不是我想要做的.我想使用流来生成文件并将流传输到S3,只要我生成它.

osm*_*tes 15

这是使用NodeJS的API接口问题ReadableStreams.只需注释与listen事件相关的代码'data',就可以解决问题.

const fs = require('fs')
const S3 = require('aws-sdk/clients/s3')

const s3 = new S3()

const send = async () => {
  const rs = fs.createReadStream('/home/osman/Downloads/input.txt')
  rs.on('open', () => {
    console.log('OPEN')
  })
  rs.on('end', () => {
    console.log('END')
  })
  rs.on('close', () => {
    console.log('CLOSE')
  })
  // rs.on('data', (chunk) => {
  //   console.log('DATA: ', chunk)
  // })

  console.log('START UPLOAD')

  const response = await s3.upload({
    Bucket: 'test-bucket',
    Key: 'output.txt',
    Body: rs,
  }).promise()

  console.log('response:')
  console.log(response)
}

send().catch(err => { console.log(err) })
Run Code Online (Sandbox Code Playgroud)

虽然这是一个奇怪的API,当我们听'data'事件时,ReadableStream启动流动模式(听一个事件改变发布者/ EventEmitter状态?是的,非常容易出错...).出于某种原因,S3需要暂停 ReadableStream.如果它工作rs.on('data'...)后放await s3.upload(...)了.如果我们把rs.pause()rs.on('data'...)和befote await s3.upload(...),它也能工作.

现在,它发生了什么?我还不知道......

但问题解决了,即使没有完全解释.