使用 AWS S3 getObject 中的读取流读取并上传到不同的存储桶

问题描述 投票:0回答:1

我正在尝试从第三方 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 来实现这一点。

javascript node.js amazon-web-services amazon-s3 nodejs-stream
1个回答
2
投票

正如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
调用挂起。请参阅此问题

您可以通过使用此来同步两个不同的流来修复它。可以在here找到如何实现这一目标的示例。

© www.soinside.com 2019 - 2024. All rights reserved.