首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用node js转换流作为读取流?

如何使用node js转换流作为读取流?
EN

Stack Overflow用户
提问于 2018-05-26 07:37:19
回答 1查看 1.6K关注 0票数 2

我正在尝试使用node.js中的AWS-SDK下载、就地修改和重新上传文件到亚马逊S3。我是node的新手,在谷歌搜索之后,我选择尝试使用streams来实现此逻辑。我通过继承stream.Transform并提供一个transform函数创建了一个自定义的转换流。我目前的实现是:

// Download and modify file.
var outputStream = s3.getObject(getParams).
    createReadStream().
    pipe(transformStream);

// Upload modified file by passing outputStream as body to s3.putObject.
// s3.putObjectWrapper is a promise wrapper for the api function putObject.
s3.putObjectWrapper({body: outputStream, ...}).
    then((data) => {
        logger.debug("Put Success: ", {data: data});
    }).
    catch((err) => {
        logger.error("Put Error: ", {error: err});
    });

这将产生以下错误输出:

error: Put Error: message=Cannot determine length of [object Object], objectMode=false, highWaterMark=16384, head=null, tail=null, length=0, length=0, pipes=null, pipesCount=0, flowing=null, ended=false, endEmitted=false, reading=false, sync=false, needReadable=true, emittedReadable=false, readableListening=false, resumeScheduled=false, defaultEncoding=utf8, ranOut=false, awaitDrain=0, readingMore=false, decoder=null, encoding=null, readable=true, domain=null, end=function

我已经在这里阅读了有关streams的节点文档(参见下面的链接)。我没有发现它们有什么帮助,而且我不确定是否还必须在我的自定义transform流类中实现stream.Read方法来支持流的可读性,transformStream就是其中的一个实例。还要注意,函数s3.putObject接受缓冲区、流或字符串作为其主体。因此,如果我可以使用缓冲区来实现相同的功能,而不是将流传递给putObject,这将是很有用的。node.js streams:https://nodejs.org/dist/latest-v10.x/docs/api/stream.html。aws-sdk S3接口:https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property

总而言之,我不确定我的实现出了什么问题,也不确定使用streams是否是完成我正在尝试执行的任务的可行方法。

EN

回答 1

Stack Overflow用户

发布于 2018-05-26 08:55:28

有一个带有s3.putObjectissue,它只支持用fs.creatReadStream创建的流,但是您可以解决这个问题,自己设置流的长度。问题是,您需要事先知道流的长度,如果您不知道它的长度,那么很可能是因为您正在转换它,所以您需要将它通过管道传输到一个文件,然后使用fs.createReadStream传递一个可读的流。或者更好的做法是使用s3.upload,这将允许您使用任何可读的流。

使用s3.upload

const params = { Bucket: 'bucket', Key: 'Filename', Body: stream };
s3.upload(params, (err, data) => {
  console.log(err, data);
});

使用s3.putObject

// This will work if you know the length beforehand
outputStream.length = getStreamLength(); 

s3.putObjectWrapper({ body: outputStream })

下面的方法将会起作用。即使可能不是任何人在使用streams时所期望的。

const writeStream = fs.createWriteStream('/tmp/testing');

var outputStream = s3.getObject(getParams)
    .createReadStream().
    .pipe(transformStream)
    .pipe(writeStream)


 writeStream.on('close', () => {

    const readStream = fs.createReadStream('/tmp/testing');

    s3.putObjectWrapper({
      body: readStream
    })
    .then(data => {
      logger.debug("Put Success: ", { data: data });
    })
    .catch(err => {
      logger.error("Put Error: ", { error: err });
    });
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50538028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档