【问题标题】:How to get contents of a text file from AWS s3 using a lambda function?如何使用 lambda 函数从 AWS s3 获取文本文件的内容?
【发布时间】:2015-08-19 12:24:28
【问题描述】:

我想知道是否可以为 AWS 设置一个 lambda 函数,只要将新文本文件上传到 s3 存储桶中就会触发。在函数中,我想获取文本文件的内容并以某种方式处理它。我想知道这是否可能......?

例如,如果我上传 foo.txt,内容为 foobarbaz,我想以某种方式在我的 lambda 函数中获取 foobarbaz,以便我可以用它做一些事情。我知道我可以从 getObject 或类似方法中获取元数据。

谢谢!

【问题讨论】:

    标签: javascript amazon-web-services amazon-s3 aws-lambda


    【解决方案1】:

    S3 对象键和存储桶名称通过 event 参数传递到您的 Lambda 函数。然后,您可以从 S3 获取对象并读取其内容。

    从 Lambda event 中检索存储桶和对象键的基本代码如下:

    exports.handler = function(event, context, callback) {
       const bkt = event.Records[0].s3.bucket.name;
       const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    };
    

    一旦你有了bucket和key,你就可以调用getObject来检索对象了:

    const AWS = require('aws-sdk');
    const s3 = new AWS.S3();
    
    exports.handler = function(event, context, callback) {
        
        // Retrieve the bucket & key for the uploaded S3 object that
        // caused this Lambda function to be triggered
        const Bucket = event.Records[0].s3.bucket.name;
        const Key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    
        // Retrieve the object
        s3.getObject({ Bucket, Key }, function(err, data) {
            if (err) {
                console.log(err, err.stack);
                callback(err);
            } else {
                console.log("Raw text:\n" + data.Body.toString('ascii'));
                callback(null, null);
            }
        });
    };
    

    这是一个更新的 JavaScript 示例,使用 ES6 风格的代码和承诺,减去错误处理:

    const AWS = require('aws-sdk');
    const s3 = new AWS.S3();
    
    exports.handler = async (event, context) => {
      const Bucket = event.Records[0].s3.bucket.name;
      const Key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
      const data = await s3.getObject({ Bucket, Key }).promise();
      console.log("Raw text:\n" + data.Body.toString('ascii'));
    };
    

    许多发帖人要求使用 Java 中的等价物,所以这里有一个示例:

    package example;
    
    import java.net.URLDecoder;
    
    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import com.amazonaws.services.lambda.runtime.events.S3Event;
    import com.amazonaws.services.s3.AmazonS3;
    import com.amazonaws.services.s3.AmazonS3Client;
    import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;
    
    public class S3GetTextBody implements RequestHandler<S3Event, String> {
     
        public String handleRequest(S3Event s3event, Context context) {
            try {
                S3EventNotificationRecord record = s3event.getRecords().get(0);
    
                // Retrieve the bucket & key for the uploaded S3 object that
                // caused this Lambda function to be triggered
                String bkt = record.getS3().getBucket().getName();
                String key = record.getS3().getObject().getKey().replace('+', ' ');
                key = URLDecoder.decode(key, "UTF-8");
    
                // Read the source file as text
                AmazonS3 s3Client = new AmazonS3Client();
                String body = s3Client.getObjectAsString(bkt, key);
                System.out.println("Body: " + body);
                return "ok";
            } catch (Exception e) {
                System.err.println("Exception: " + e);
                return "error";
            }
        }
    }
    

    【讨论】:

    • 对,但除非我弄错了,data 不是在 console.log('CONTENT TYPE:', data.ContentType); 元数据中,而不是文件的内容吗?
    • 它为您提供事件数据,但不提供文件本身的数据,iirc。
    • @jstnchng 是的,那是元数据。但我认为您要求的是“foobarbaz”,它是实际 S3 对象的内容,因此您必须调用 GetObject 来检索该对象。
    • 我想尝试与问题中指定的相同的方法,但改用 java,有人可以指定一些 java 示例的链接吗?
    • @cedzz 这是完整的 S3 密钥,例如 archive/cats/fluffykins.jpg。
    【解决方案2】:

    您可以使用data.Body.toString('ascii') 来获取文本文件的内容,假设文本文件是使用ascii 格式编码的。您还可以将其他编码类型传递给该函数。查看Node-Buffer了解更多详情。

    【讨论】:

    • 工作就像一个魅力,顺便说一句,你能看看我的类似问题吗? stackoverflow.com/questions/34056133/…
    • 嗨,我想将相同的数据写入 DynamoDB,以便我想直接从回调函数返回数据对象(在 s3.getObject 方法中传递)我如何从这里的函数中提取数据?
    【解决方案3】:

    我在 python 3.6 环境中使用 lambda 函数。 下面的代码将读取存储桶 my_s3_bucket 中文件 main.txt 的内容。确保根据您的需要替换存储桶的名称和文件名。

    def lambda_handler(event, context):
        # TODO implement
        import boto3
    
        s3 = boto3.client('s3')
        data = s3.get_object(Bucket='my_s3_bucket', Key='main.txt')
        contents = data['Body'].read()
        print(contents)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-22
      • 2018-01-26
      • 2018-12-07
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 2019-05-02
      • 2016-07-27
      相关资源
      最近更新 更多