我正在尝试从第三方 AWS S3 存储桶读取
.gz
格式的文件。我需要处理文件中的数据并将文件上传到我们自己的S3 Bucket。
为了读取文件,我从 S3.getBucket 创建一个 readStream,如下所示:
const fileStream = externalS3.getObject({Bucket: <bucket-name>, Key: <key>}).createReadStream();
为了使代码更高效,我计划使用相同的
fileStream
来处理内容并上传到我们自己的S3。我有下面的代码,它不会将文件上传到内部 S3 存储桶。
import Stream from "stream";
const uploadStream = fileStream.pipe(new stream.PassThrough());
const readStream = fileStream.pipe(new stream.PassThrough());
await internalS3.upload({Bucket:<bucket-name>, Key: <key>, Body: uploadStream})
.on("httpUploadProgress", progress => {console.log(progress)})
.on("error", error => {console.log(error)})
.promise();
readStream.pipe(createGunzip())
.on("error", err =>{console.log(err)})
.pipe(JSONStream.parse())
.on("data", data => {console.log(data)});
但是,下面的代码成功地将文件上传到内部 s3 存储桶。
const uploadStream = fileStream.pipe(new stream.PassThrough());
await internalS3.upload({Bucket:<bucket-name>, Key: <key>, Body: uploadStream})
.on("httpUploadProgress", progress => {console.log(progress)})
.on("error", error => {console.log(error)})
.promise();
我在这里做错了什么?
注意:如果我使用单独的
fileStream
来上传和读取数据,则效果很好。但是,我需要使用相同的 fileStream 来实现这一点。
正如OP提到的,您尝试上传到S3的文件具有相对较大的大小(~1 GB)。这里正在创建两个流,通过管道传输单个
fileStream
:
const uploadStream = fileStream.pipe(new stream.PassThrough());
const readStream = fileStream.pipe(new stream.PassThrough());
虽然
readStream
上的操作耗时较少,但 uploadStream
负责通过网络将文件上传到远程位置(在本例中为 S3),这需要相对更多的时间。这也意味着 readStream
正在以更高的速率从 fileStream
拉取/请求数据。当 readStream
完成时,fileStream
已被消耗,并且对 .upload
的 aws sdk
调用挂起。请参阅此问题。