我正在尝试使用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是否是完成我正在尝试执行的任务的可行方法。
发布于 2018-05-26 08:55:28
有一个带有s3.putObject
的issue,它只支持用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 });
});
});
https://stackoverflow.com/questions/50538028
复制相似问题