You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda读取S3中CSV文件统计行数失败求助

问题分析

你的代码核心问题是流处理的异步性:doc.Body.pipe()是基于Node.js流的异步操作,它不会阻塞后续代码执行。当你调用s3.putObject()时,CSV解析的data和end事件还没触发,rowCount仍然是初始值0,所以输出文件里行数为0;而控制台日志里的rowCount递增,是后续流处理时才触发的事件逻辑。

修复方案

将流处理逻辑封装成Promise,等待流完全解析完成后再执行写入输出桶的操作,同时避免使用全局变量防止Lambda并发调用时的变量污染。

修改后的代码:

import { S3 } from '@aws-sdk/client-s3';
import { parse } from 'csv';

const s3 = new S3();

export const handler = async (event) => {
  const bucket = event.Records[0].s3.bucket.name;
  const key = event.Records[0].s3.object.key;

  const params = {
    Bucket: bucket,
    Key: key,
  };

  // 下载文件
  const doc = await s3.getObject(params);

  // 将流解析封装为Promise,等待解析完成
  const rowCount = await new Promise((resolve) => {
    let count = 0;
    doc.Body.pipe(
      parse({
        delimiter: ",",
        columns: true,
      })
      .on('data', () => {
        count++;
        console.log(count);
      })
      .on('end', () => {
        console.log(`最终行数:${count}`);
        resolve(count);
      })
    );
  });
  
  const date = new Date().toLocaleString();
  const outputBucket = 'outputbucket';
  const outputKey = 'output.txt';
  const outputParams = {
    Bucket: outputBucket,
    Key: outputKey,
    Body: `Processed ${rowCount} rows in file ${key} from ${bucket} on ${date}`,
  };
      
  await s3.putObject(outputParams);
};
关键修改点
  • 用Promise包裹流解析逻辑,在end事件触发时resolve统计好的行数,确保后续代码等待解析完成再执行。
  • 将计数变量移到handler内部的Promise中,避免全局变量导致的Lambda执行环境复用带来的数据污染。
  • 移除end事件里的不必要async声明,简化逻辑。

内容的提问来源于stack exchange,提问作者luisddr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:33:14