node.js - Javascript AWS SDK S3上传方法与正文流生成空文件

标签 node.js amazon-s3 upload stream

我正在尝试通过 fs 模块中的 ReadableStream 使用 s3 中的方法 upload

documentation表示可以在 Bodyparam:

处使用 ReadableStream

Body — (Buffer, Typed Array, Blob, String, ReadableStream) Object data.

另外上传方法描述为:

Uploads an arbitrarily sized buffer, blob, or stream, using intelligent concurrent handling of parts if the payload is large enough.

另外,这里:Upload pdf generated to AWS S3 using nodejs aws sdk @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) })

它得到这个输出:

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' }

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

有人知道我做错了什么吗?

如果我在 Body 上传递一个缓冲区,它就可以工作。

Body: Buffer.alloc(8 * 1024 * 1024, 'something'), 

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

最佳答案

这是使用 NodeJS 的 API 接口(interface)问题 ReadableStreams . 只需注释监听事件相关的代码 '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) })

虽然这是一个奇怪的 API,但当我们收听 'data'事件,ReadableStream启动 flowing 模式(监听改变发布者/EventEmitter 状态的事件?是的,非常容易出错......)。出于某种原因,S3 需要 暂停 ReadableStream .如果把 rs.on('data'...)await s3.upload(...) 之后有用。如果我们把 rs.pause()rs.on('data'...) 之后和之前 await s3.upload(...) ,它也有效。

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

但是问题已经解决了,即使没有完全解释。

关于node.js - Javascript AWS SDK S3上传方法与正文流生成空文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44145813/

相关文章:

node.js - node是单线程的,为什么在node.js中需要连接池?

php - html和主流浏览器支持的不同视频格式

php - 如何在php中重命名上传的图片

jquery - 使用phonegap将文件作为流上传到cloudinary

node.js - 如何使用存储过程是sequelize orm

javascript - Socket.io 需要很长时间才能触发断开连接事件

python - 如何去除图像的白色背景并使其透明?

javascript - 跟随重定向时的授权 header

ios - 上传到s3,iOS成功回调

带 SSL 的 WordPress