【问题标题】:In Node.js Create read stream from S3 object or web URL, and PassThrough the read stream to multiple pipes在 Node.js 中从 S3 对象或 Web URL 创建读取流,并将读取流传递到多个管道
【发布时间】:2021-08-22 17:52:46
【问题描述】:

在基于 Node.js12.x 的 Lambda 函数中,我正在尝试

  1. 从 S3 下载对象
  2. 如果 S3 中不存在对象,则从 Web 下载文件
  3. 通过下载的数据,无论其如何到达多个写入流

我试过了

var request = require('request');

const readStream = ({ Bucket, Key }) => {

  s3.getObjectMetadata({ Bucket, Key })
    .promise().then(() => {
      return s3.getObject().createReadStream();
    })
    .catch(error => {
      if (error.statusCode === 404) {
        return request.get('http://example.com/' + Key);
      }
    });
};

readStream({ ... })
  .pipe(sharp().resize(w, h).toFormat('png'))
  .pipe(writeStream);

如果对象在 s3 中可用,上述方法有效,但 catch 块不起作用。

我需要awaitrequest.get 上的承诺吗?

我也尝试过没有运气

http.get('http://example.com/' + Key, function(response) { 
    return response;
});

【问题讨论】:

    标签: node.js amazon-web-services amazon-s3


    【解决方案1】:

    首先我们需要创建一个检查对象是否存在于桶中的promise

    const isObjectExists = (params) => {
      return s3.headObject(params)
               .promise()
               .then(
                 () => true,
                 (error) => {
                   if (err.statusCode === 404) {
                     return false;
                   }
                   throw error;
                 }
               )}
    
    const awsParams = { Bucket: ..., Key: s3ObjectKey };
    const exists = await isObjectExists(awsParams);
    

    接下来,我们需要从 s3 或 Web URL 创建一个读取流。

    使用已弃用的 request 包,因为我无法使用 http 让事情正常工作。

    let readStream = null;
    if (exists) {
        readStream = s3.getObject(awsParams).createReadStream();
    } else {
        readStream = request.get('http://example.com/' + s3ObjectKey);
    }
    

    将刚刚创建的readStream 传递给处理,最后传递给上传流

    const pass = new PassThrough();
    
    readStream.
      .pipe(sharp().resize(w, h).toFormat('png'))
      .pipe(s3.upload({
        Body: pass,
        Bucket,
        ContentType: 'image/png',
        s3ObjectKey + '-resized'
      }).promise());
    
    const uploadedData = await pass;
    

    添加一些先决条件

    import awS3 from 'aws-sdk/clients/s3';
    import { PassThrough } from 'stream'
    import * as request from 'request';
    
    const s3 = new awS3({signatureVersion: 'v4'});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 2022-01-09
      • 2020-01-12
      • 2020-03-12
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多