【问题标题】:Read a file line by line using Lambda / S3使用 Lambda / S3 逐行读取文件
【发布时间】:2019-03-18 01:01:06
【问题描述】:

我想逐行读取位于 S3 上的文件。我尝试了以下在网上搜索的代码,但 Lambda 函数在没有调用任何 readline 回调的情况下退出。我做错了什么?

const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
const readline = require('readline');

exports.handler = async (event, context, callback) => {
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };

    const s3ReadStream = s3.getObject(params).createReadStream();

    const rl = readline.createInterface({
      input: s3ReadStream,
      terminal: false
    });

    rl.on('line', (line) => {
      console.log(`Line from file: ${line}`);
    });
    rl.on('error', () => {
        console.log('error');
    });
    rl.on('close', function () {
        console.log('closed');
        context.succeed();
    });
    console.log('done');
};

【问题讨论】:

    标签: node.js amazon-s3 aws-lambda aws-sdk


    【解决方案1】:

    getObject 不仅仅返回存储在 S3 中的对象。它返回一个 JSON 对象,其 Body 字段包含存储到 S3 的对象的 blob。另请参阅文档hereResponse 部分。

    【讨论】:

    • 谢谢。我基于此代码:gist.github.com/maxrabin/e3e51abc365cd3f54d78你知道我怎样才能完成我想要的吗?
    • @Raisen 有趣。如果您链接到的代码曾经有效,那么我的回答可能是错误的。突出的是您混合使用了asynccontext.succeed(传统风格的Lambda 编程)。为什么不坚持链接中出现的代码,或者只使用 Promise 重写它?
    • 我已经找到了问题所在。你是对的,承诺有助于解决这个问题。感谢您的帮助!
    【解决方案2】:

    我发现了问题。我已经有一段时间没有在 Lambda 上编码了,我认为它只会在调用 context 时退出。我现在正在等待解决承诺(或拒绝,我将在稍后实施)。

    const aws = require('aws-sdk');
    const s3 = new aws.S3({ apiVersion: '2006-03-01' });
    const readline = require('readline');
    
    exports.handler = async (event, context, callback) => {
        const bucket = event.Records[0].s3.bucket.name;
        const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
        const params = {
            Bucket: bucket,
            Key: key,
        };
        const s3ReadStream = s3.getObject(params).createReadStream();
    
        const rl = readline.createInterface({
          input: s3ReadStream,
          terminal: false
        });
    
        let myReadPromise = new Promise((resolve, reject) => {
    
            rl.on('line', (line) => {
              console.log(`Line from file: ${line}`);
            });
            rl.on('error', () => {
                console.log('error');
            });
            rl.on('close', function () {
                console.log('closed');
                resolve();
            });
        });
    
        try { await myReadPromise; }
        catch(err) {
            console.log('an error has occurred');
        }
    
        console.log('done reading!');
    };
    

    【讨论】:

    • 天哪……你救了我的命……我花了 8 个小时试图弄清楚为什么它不起作用。这是您的确切解决方案....
    • 感谢分享您的解决方案!我有同样的问题,但无法让它运行。我的代码在本地机器上运行良好,但在 lambda 上超时。我尝试运行您的代码并且也超时。似乎从未调用过'line'回调。您是否采取了任何其他步骤来完成这项工作?
    • @davidrac 你增加了 lambda 函数超时时间吗?
    猜你喜欢
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    相关资源
    最近更新 更多