【问题标题】:Download image from S3 bucket to Lambda temp folder (Node.js)将图像从 S3 存储桶下载到 Lambda 临时文件夹 (Node.js)
【发布时间】:2016-12-22 16:49:37
【问题描述】:

大家好。

我有一个简单的问题:如何将图像从 S3 存储桶下载到 Lambda 函数临时文件夹进行处理?基本上,我需要将它附加到电子邮件中(我可以在本地测试时这样做)。

我试过了:

s3.download_file(bucket, key, '/tmp/image.png')

以及(不确定哪些参数可以帮助我完成工作):

s3.getObject(params, (err, data) => {
    if (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}.`;
        console.log(message);
        callback(message);
    } else {

        console.log('CONTENT TYPE:', data.ContentType);
        callback(null, data.ContentType);
    }
});

就像我说的,一个简单的问题,由于某种原因我找不到解决方案。

谢谢!

【问题讨论】:

    标签: node.js amazon-web-services amazon-s3 aws-lambda sendgrid


    【解决方案1】:

    您可以使用 aws s3 api 获取图像,然后使用 fs 将其写入 tmp 文件夹。

    var params = {   Bucket: "BUCKET_NAME",   Key: "OBJECT_KEY" };  
    
    s3.getObject(params, function(err, data){   if (err) {
        console.error(err.code, "-", err.message);
        return callback(err);   }
    
      fs.writeFile('/tmp/filename', data.Body, function(err){
        if(err)
          console.log(err.code, "-", err.message);
    
        return callback(err);   
      }); 
    });
    

    出于好奇,您为什么需要编写文件才能附加它?将文件写入磁盘似乎有点多余,以便您可以从磁盘读取它

    【讨论】:

    • 我正在使用 SendGrid,因此似乎必须将文件存在于本地磁盘上才能附加它。你是说这不是必须的吗?
    • 我对 SendGrid 一点也不熟悉,所以我不确定,但我的想法是你会将它下载到内存中,我认为这可能是一个问题,具体取决于文件大小。
    • @JonathanSeed 我实际上遇到了这个问题,我正在使用getObject 读取一个 150-200mb 的文本文件,这使我的 Lambda 函数达到其最大内存限制。是否有解决方法或为什么内存限制如此之低?
    • @V.Samma 您可以在控制台的“高级设置”下为 lambda 函数配置内存。我相信默认值为 128 mb。
    • @JonathanSeed 我可能还不够清楚。通过达到其最大内存限制,我的意思是我已经为我的 lambda 函数设置了最大内存,即 1536MB,当我的 lambda 函数尝试读取 2 个文件(一个是几 KB-s,一个是 150- 200MB-s),然后将它们连接为字符串值并将结果写回 S3。
    【解决方案2】:

    如果您直接将其写入文件系统,您也可以do it with streams。它可能会更快/对内存更友好,尤其是在 Lambda 等内存受限的环境中。

    var fs = require('fs');
    var path = require('path');
    
    var params = {
        Bucket: "mybucket",
        Key: "image.png"
    };
    
    var tempFileName = path.join('/tmp', 'downloadedimage.png');
    var tempFile = fs.createWriteStream(tempFileName);
    
    s3.getObject(params).createReadStream().pipe(tempFile);
    

    【讨论】:

    • 您知道createReadStream() 是否让aws-sdk 触发多个 GET 调用,或者它只执行一个然后流式传输数据?我担心这个解决方案的成本
    • 这是什么路径?
    • @Sinn 我相信它应该只触发一个 GET 调用。它和普通的 getObject 做同样的事情,但只是暴露了底层流
    • @VikasSatpute 我编辑添加路径,感谢您指出
    【解决方案3】:
    // Using NodeJS version 10.0 or later and promises
    
    const fsPromise = require('fs').promises;
    
    try {
        const params = {
            Bucket: 's3Bucket',
            Key: 'file.txt',
        };
    
        const data = await s3.getObject(params).promise();
    
        await fsPromise.writeFile('/tmp/file.txt', data.Body);
    
    } catch(err) {
        console.log(err);
    }
    

    【讨论】:

    • 请在您的回答中添加一些细节
    猜你喜欢
    • 2015-05-20
    • 2020-12-30
    • 2013-10-15
    • 1970-01-01
    • 2021-04-19
    • 2019-02-16
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    相关资源
    最近更新 更多