如何使用 lambda 函数从 AWS s3 获取文本文件的内容?

如何使用 lambda 函数从 AWS s3 获取文本文件的内容?

问题描述:

我想知道是否可以为 AWS 设置一个 lambda 函数,每当一个新的文本文件上传到 s3 存储桶时触发.在函数中,我想获取文本文件的内容并以某种方式对其进行处理.我想知道这是否可能......?

I was wondering if I could set up a lambda function for AWS, triggered whenever a new text file is uploaded into an s3 bucket. In the function, I would like to get the contents of the text file and process it somehow. I was wondering if this was possible...?

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

For example, if I upload foo.txt, with contents foobarbaz, I would like to somehow get foobarbaz in my lambda function so I can do stuff with it. I know I can get metadata from getObject, or a similar method.

谢谢!

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

The S3 object key and bucket name are passed into your Lambda function via the event parameter. You can then get the object from S3 and read its contents.

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

Basic code to retrieve bucket and object key from the Lambda event is as follows:

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来检索对象了:

Once you have the bucket and key, you can call getObject to retrieve the object:

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:
" + data.Body.toString('ascii'));
            callback(null, null);
        }
    });
};

这是一个使用 ES6 样式代码和 promise 的更新 JavaScript 示例,减去错误处理:

Here's an updated JavaScript example using ES6-style code and promises, minus error-handling:

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:
" + data.Body.toString('ascii'));
};

许多发帖人要求使用 Java 中的等效项,因此这里是一个示例:

A number of posters have asked for the equivalent in Java, so here's an example:

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