将一个流导入到s3.upload()函数中。
将一个流导入到s3.upload()函数中。
我目前正在使用一个名为 s3-upload-stream 的node.js插件,将非常大的文件流传输到Amazon S3。它使用多部分API,大部分情况下它的工作非常好。
然而,该模块已经过时了,我已经必须对其进行修改(作者已将其弃用)。今天我遇到了另一个Amazon的问题,我真的很想采用作者的建议,开始使用官方的aws-sdk来完成我的上传。
但是。
官方SDK似乎不支持将流与 s3.upload()
管道连接。s3.upload的本质是你必须将可读流作为参数传递给 S3 构造函数。
我有大约120个以上的用户代码模块,用于各种文件处理,它们对其输出的最终目的地是无感知的。引擎将它们的可传输可写输出流直接传递给它们,它们将其传递给它们的输出。我不能将 AWS.S3
对象传递给它们,并要求它们在其上调用 upload()
,而不需要添加代码来到所有的模块。我使用 s3-upload-stream
的原因是因为它支持管道连接。
是否有一种方法使得aws-sdk的 s3.upload()
可以被我用管道连接的方式传输流?
admin 更改状态以发布 2023年5月21日
回答有点晚,希望能帮助到其他人。你可以同时返回可写流和承诺,这样你就可以在上传完成时获取响应数据。
const AWS = require('aws-sdk'); const stream = require('stream'); const uploadStream = ({ Bucket, Key }) => { const s3 = new AWS.S3(); const pass = new stream.PassThrough(); return { writeStream: pass, promise: s3.upload({ Bucket, Key, Body: pass }).promise(), }; }
你可以按照以下方式使用该函数:
const { writeStream, promise } = uploadStream({Bucket: 'yourbucket', Key: 'yourfile.mp4'}); const readStream = fs.createReadStream('/path/to/yourfile.mp4'); const pipeline = readStream.pipe(writeStream);
现在你可以检查承诺:
promise.then(() => { console.log('upload completed successfully'); }).catch((err) => { console.log('upload failed.', err.message); });
或使用async/await:
try { await promise; console.log('upload completed successfully'); } catch (error) { console.log('upload failed.', error.message); }
或者,由于stream.pipe()返回stream.Writable,目标(上面的writeStream变量)允许链式管道,我们还可以使用其事件:
pipeline.on('close', () => { console.log('upload successful'); }); pipeline.on('error', (err) => { console.log('upload failed', err.message) });
使用node.js的stream.PassThrough()
流来包装S3的upload()
函数。
这里是一个例子:
inputStream .pipe(uploadFromStream(s3)); function uploadFromStream(s3) { var pass = new stream.PassThrough(); var params = {Bucket: BUCKET, Key: KEY, Body: pass}; s3.upload(params, function(err, data) { console.log(err, data); }); return pass; }