NodeJS:使用流将图像文件上传到S3存储桶

12 浏览
0 Comments

NodeJS:使用流将图像文件上传到S3存储桶

我目前正在使用一个叫做s3-upload-stream的node.js插件,将非常大的文件流式传输到Amazon S3。它使用了多部分API,大部分情况下运行得很好。\n然而,这个模块已经显得有些过时了,我已经不得不对其进行修改(作者也已经将其弃用)。今天我遇到了另一个与Amazon相关的问题,我真的很想采纳作者的建议,开始使用官方的aws-sdk来完成我的上传操作。\n但是。\n官方的SDK似乎不支持对s3.upload()进行流式传输。s3.upload的特性是必须将可读流作为参数传递给S3构造函数。\n我大约有120多个用户代码模块进行各种文件处理,它们对最终输出的目的地是无知的。引擎会给它们一个可传输的可写输出流,它们会将数据传输到这个流中。我不能给它们一个AWS.S3对象,并要求它们调用upload()方法,而不对所有模块添加代码。我之所以使用s3-upload-stream是因为它支持流式传输。\n有办法让aws-sdk的s3.upload()支持流式传输吗?

0
0 Comments

问题的原因是函数在上传完成之前就结束了,因此是不正确的。解决方法是使用可读流正确地进行管道操作。可以进一步使用ManagedUpload来输出进度信息。aws-sdk现在在2.3.0+版本中内置了promise,所以不再需要手动处理。另外,还有一个关于dest.on的错误,通过使用streaming-s3包可以解决这个问题。最后,还有一个关于如何在不监听httpUploadProgress事件和不打印进度的情况下开始或结束流上传的问题。

0
0 Comments

问题的原因是使用流将图像文件上传到S3存储桶时出现了错误。解决方法是返回可写流和Promise,以便在上传完成时获取响应数据。

首先,我们需要引入依赖库:

const AWS = require('aws-sdk');
const stream = require('stream');

然后,我们定义一个名为`uploadStream`的函数,该函数接受一个包含存储桶和键的对象作为参数。函数内部创建了一个S3实例和一个可传递的流对象,并返回一个包含可写流和Promise的对象:

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来处理结果:

promise.then(() => {
  console.log('上传成功');
}).catch((err) => {
  console.log('上传失败', err.message);
});

或者使用async/await语法:

try {
    await promise;
    console.log('上传成功');
} catch (error) {
    console.log('上传失败', error.message);
}

另外,由于`stream.pipe()`返回的是可写流,我们还可以使用它的事件来处理上传结果:

pipeline.on('close', () => {
   console.log('上传成功');
 });
 pipeline.on('error', (err) => {
   console.log('上传失败', err.message)
 });

以上是解决使用流将图像文件上传到S3存储桶的问题的方法。如果你遇到了类似的错误,可以参考这个解决方案。

0
0 Comments

问题的出现原因:用户想要使用Node.js将图像文件上传到S3存储桶,但是上传后的文件大小为0字节,无法正确上传文件。

解决方法:将S3的upload()函数使用node.js的stream.PassThrough()流进行封装,然后将数据流通过pipe()方法传递给S3进行上传。

代码示例:

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字节文件的问题。其中stream.PassThrough()流的作用是接受写入的字节并将其输出。这样可以返回一个可写流供aws-sdk在写入时读取。同时,需要将s3.upload()方法的返回对象也返回,以确保上传完成。

用户进一步提到,如果将content-type更改为text/plain,则上传正常。还有其他用户表示,这种方法与直接将可读流传递给Body参数并没有本质区别,因为AWS SDK仍会调用PassThrough流的read()方法。

最后,用户还询问了代码中的s3和stream参数的来源,这些参数需要用户自行传入。

通过整理上述内容,我们可以得出以下文章:

NodeJS:使用流将图像文件上传到S3存储桶

在Node.js中,有时我们需要将文件上传到S3存储桶。然而,有些用户在使用流进行上传时遇到了问题,上传后的文件大小为0字节,无法正确上传文件。下面是一个解决上传问题的方法:

首先,我们需要使用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;
}

通过将数据流通过pipe()方法传递给S3进行上传,可以解决上传0字节文件的问题。stream.PassThrough()流的作用是接受写入的字节并将其输出,以便返回一个可写流供aws-sdk在写入时读取。同时,需要将s3.upload()方法的返回对象也返回,以确保上传完成。

有些用户提到,将content-type更改为text/plain后,上传就正常了。还有用户对上述方法提出了疑问,认为其与直接将可读流传递给Body参数没有本质区别,因为AWS SDK仍会调用PassThrough流的read()方法。

最后,需要注意的是,代码中的s3和stream参数需要用户自行传入。

通过以上方法,我们就可以成功使用Node.js将图像文件上传到S3存储桶了。

0