将一个流导入到s3.upload()函数中。

8 浏览
0 Comments

将一个流导入到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日
0
0 Comments

回答有点晚,希望能帮助到其他人。你可以同时返回可写流和承诺,这样你就可以在上传完成时获取响应数据。

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)
 });

0
0 Comments

使用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;
}

0