在Node.js中将写入流从writestream上传到S3

16 浏览
0 Comments

在Node.js中将写入流从writestream上传到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

问题的出现原因是在接受的答案中,函数在上传完成之前就已经结束了,因此是不正确的。 解决方法是使用正确的代码来正确地从可读流中获取数据并上传到S3。代码示例如下:

async function uploadReadableStream(stream) {
  const params = {Bucket: bucket, Key: key, Body: stream};
  return s3.upload(params).promise();
}
async function upload() {
  const readable = getSomeReadableStream();
  const results = await uploadReadableStream(readable);
  console.log('upload complete', results);
}

你也可以使用`ManagedUpload`来输出上传进度信息,示例如下:

const manager = s3.upload(params);
manager.on('httpUploadProgress', (progress) => {
  console.log('progress', progress) // { loaded: 4915, total: 192915, part: 1, key: 'foo.jpg' }
});

通过使用`ManagedUpload`,可以方便地输出上传进度信息。 还可以参考`ManagedUpload`的相关文档以及可用事件的列表。

在aws-sdk的2.3.0版本及以上,已经内置了Promise,因此不再需要手动处理。可以直接使用`s3.upload(params).promise().then(data => data).catch(error => error)`来处理上传操作。

关于错误`TypeError: dest.on is not a function`,这可能是一个Node.js问题。可以尝试使用`streaming-s3`这个包来解决,这个包提供了所需的功能。

还有一个用户提到,接受的答案虽然被认为是不完整的,但是不适用于将数据从其他地方流式传输到`s3.upload`。 如果能更新答案以接受来自其他地方的流式输出将非常有帮助。

还有一个用户提到,如果不使用`manager.on("httpUploadProgress"...`这一行,流式上传将无法开始或结束。该用户想知道如何在不监听`httpUploadProgress`事件和不打印进度的情况下启动或结束流式上传。

0
0 Comments

最近我遇到了一个问题,希望能对其他人有所帮助。在Node.js中,我想将数据从Writable Stream上传到S3。我找到了一个解决方法,并将其分享给大家。

问题的原因是在上传过程中出现了一个错误,错误信息是"unsupported body payload object when trying to upload to amazon s3 using stream"。我发现这个错误是因为在上传过程中没有正确处理Promise。

为了解决这个问题,我编写了以下代码:

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的状态来判断上传是否成功:

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()的事件来判断上传是否成功:

pipeline.on('close', () => {
  console.log('upload successful');
});
pipeline.on('error', (err) => {
  console.log('upload failed', err.message)
});

经过这些改进,我成功地解决了上传到S3时遇到的问题。希望这篇文章对其他人也有所帮助!

0
0 Comments

问题:如何将writestream上传到S3中?

原因:为了解决上传文件到S3的问题,需要将S3的upload()函数包装到node.js的stream.PassThrough()流中。

解决方法:

下面是一个示例代码:

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

在上述代码中,我们首先创建了一个stream.PassThrough()对象,并将其赋值给pass变量。然后,我们创建了一个params对象,其中包含了S3上传所需的BUCKET、KEY和Body参数,其中Body参数的值为pass。接下来,我们调用了S3的upload()函数,并传入params对象作为参数。upload()函数会将传入的数据流写入到S3中。最后,我们将pass对象返回,以便在其他地方继续使用。

以上就是解决将writestream上传到S3的方法。通过使用stream.PassThrough()流,我们可以将S3的upload()函数与写入流进行包装,实现文件的上传。同时,我们还可以通过返回pass对象来确保上传完成。这种方法相对于直接将可读流传递给Body参数,能够更好地控制数据流,并提供更多的代码灵活性。

但是需要注意的是,有些用户在使用这种方法时可能会遇到上传文件大小为0字节的问题。这可能与一些传递给upload()函数的参数有关,例如bucket name和key等。因此,在使用这种方法时,需要仔细检查参数的正确性。

另外,有些用户可能会遇到PassThrough流关闭的问题。如果遇到这个问题,可以尝试更改content-type为text/plain,这样可能会解决上传文件为0字节的问题。

最后,有些用户对于为什么要使用s3和stream参数有疑问。实际上,s3参数是作为uploadFromStream()函数的参数传入的,而stream参数是node.js中的一个模块,用于创建流对象。

本文介绍了如何将writestream上传到S3中的方法。通过使用stream.PassThrough()流,我们可以将S3的upload()函数与写入流进行包装,实现文件的上传。同时,我们还可以通过返回pass对象来确保上传完成。在使用这种方法时,需要注意一些可能导致上传失败的参数设置,例如bucket name和key等。希望本文对于解决将writestream上传到S3的问题有所帮助。

0