【问题标题】:Reading tab-separated files in gzip archive on S3 using Lambda (NodeJS)使用 Lambda (NodeJS) 在 S3 上的 gzip 存档中读取制表符分隔的文件
【发布时间】:2021-02-04 23:53:29
【问题描述】:

我有以下用例要解决。我需要使用 Lambda 函数(NodeJS 12)从 S3 存储桶中提取数据。创建新文件时将触发 Lambda 函数。该文件是一个 gz 存档,可以包含多个 TSV(制表符分隔)文件。对于每一行,都会从 Lambda 函数触发 API 调用。问题:

1 - 它必须是一个两步过程:解压缩 /tmp 文件夹中的存档,然后读取 TSV 文件。或者您可以直接流式传输存档文件的内容吗?

2 - 您是否有一段可以分享的代码,显示如何从 S3 存储桶及其内容 (TSV) 流式传输 GZ 文件?我发现了几个例子,但仅适用于纯 NodeJS。不是来自 Lambda/S3。

非常感谢您的帮助。

为我的第一次测试添加了一个 sn-p 代码,但它不起作用。控制台中没有记录任何数据

const csv = require('csv-parser')
const aws = require('aws-sdk');
const s3 = new aws.S3();


exports.handler = async(event, context, callback) => {
    const bucket = event.Records[0].s3.bucket.name;
    const objectKey = event.Records[0].s3.object.key;
    const params = { Bucket: bucket, Key: objectKey };
    var results = [];

    console.log("My File: "+objectKey+"\n")
    console.log("My Bucket: "+bucket+"\n")


    var otherOptions = {
        columns: true,
        auto_parse: true,
        escape: '\\',
        trim: true,
    };

    s3.getObject(params).createReadStream()
        .pipe(csv({ separator: '|' }))
        .on('data', (data) => results.push(data))
        .on('end', () => {
            console.log("My data: "+results);
        });

    return await results
};


【问题讨论】:

  • "您有可以共享这部分功能的 sn-p 代码吗?"你能定义“这部分”吗?
  • 嗨@MyStackRunnethOver。谢谢你回到我身旁。我的意思是流式传输 GZ 存档中的 TSV 文件的内容。

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


【解决方案1】:

您可能想看看wiki

虽然它的文件格式还允许连接多个[压缩文件/数据流](gzip 压缩文件只是简单地解压缩连接,就好像它们最初是一个文件[5]),但 gzip 通常只用于压缩单个文件。压缩档案通常是通过将文件集合组装成单个 tar 档案(也称为 tarball),然后使用 gzip 压缩该档案来创建的。最终压缩文件的扩展名通常为 .tar.gz 或 .tgz。

这意味着,gzip(或使用它的 Node 包)本身不足以将单个 .gz 文件解压缩为多个文件。我希望如果 S3 中的单个 .gz 项目包含多个文件,它实际上是一个 .tar.gz 或类似的压缩集合。要处理这些,请查看

Simplest way to download and unzip files in NodeJS

您可能还对node-tar感兴趣。

就一次只从存档中获取一个文件而言,这取决于压缩集合的实际内容。一些压缩方案允许一次只提取一个文件,而另一些则不允许(它们要求您一次解压缩整个文件)。 Tar does the former.

【讨论】:

    【解决方案2】:

    第一步应该是解压.tar.gz文件,使用包decompress

    // typescript code for decompressing .tar.gz file
    const decompress = require("decompress");
    try {
      const targzSrc = await aws.s3
        .getObject({
          Bucket: BUCKET_NAME,
          Key: fileRequest.key
        });
    
    
      const filesPromise = decompress(targzSrc.Body);
      const outputFileAsString = await filesPromise.then((files: any) => {
        console.log("inflated file:", files["0"].data.toString("utf-8"));
        return files["0"].data.toString("utf-8");
      });
      
      console.log("And here goes the file content:", outputFileAsString);
    
      // here should be the code that parses the CSV content using the outputFileAsString
    
    } catch (err) {
      console.log("G_ERR:", err);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      • 1970-01-01
      • 2019-03-30
      • 2021-05-14
      相关资源
      最近更新 更多