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
相关产品推荐
相关产品推荐

