在Node.js中将写入流从writestream上传到S3
在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()
成为我可以将流传输到的东西?
问题的出现原因是在接受的答案中,函数在上传完成之前就已经结束了,因此是不正确的。 解决方法是使用正确的代码来正确地从可读流中获取数据并上传到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`事件和不打印进度的情况下启动或结束流式上传。
最近我遇到了一个问题,希望能对其他人有所帮助。在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时遇到的问题。希望这篇文章对其他人也有所帮助!
问题:如何将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的问题有所帮助。