Javascript AWS 开发工具包 S3 上传方法,正文流生成空文件



我正在尝试使用来自模块fs的可读流从s3上传的方法。

文档说 ReadableStream 可以在Body参数中使用:

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

它得到这个输出:

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(输出.txt)生成的文件有 0 个字节。

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

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

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

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

这是使用 NodeJSReadableStreams的 API 接口问题。 只需注释与侦听事件相关的代码'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启动模式(侦听事件更改发布者/事件发射器状态?是的,非常容易出错...出于某种原因,S3需要暂停ReadableStream。如果在await s3.upload(...)之后放rs.on('data'...),它就可以了。如果我们把rs.pause()放在rs.on('data'...)之后,然后await s3.upload(...),它也可以工作。

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

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

  1. 检查文件/home/osman/Downloads/input.txt是否确实存在并可通过节点.js进程访问
  2. 考虑使用putObject方法

例:

const fs = require('fs');
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3();
s3.putObject({
Bucket: 'test-bucket',
Key: 'output.txt',
Body: fs.createReadStream('/home/osman/Downloads/input.txt'),
}, (err, response) => {
if (err) {
throw err;
}
console.log('response:')
console.log(response)
});

不确定这将如何与async .. await一起使用,最好先上传到AWS:S3,然后再更改流程。


更新: 尝试通过ManagedUpload直接实现上传

const fs = require('fs');
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3();
const upload = new S3.ManagedUpload({
service: s3,
params: {
Bucket: 'test-bucket',
Key: 'output.txt',
Body: fs.createReadStream('/home/osman/Downloads/input.txt')
}
});
upload.send((err, response) => {
if (err) {
throw err;
}
console.log('response:')
console.log(response)
});

相关内容

最新更新