Node 14环境AWS Lambda解析S3 CSV文件无日志输出问题求助
问题根因
- 错误使用
fs.createReadStream读取内存Buffer:fs.createReadStream接收的参数是本地文件路径字符串,而s3.getObject(params).promise()返回的file.Body是S3对象的二进制Buffer,传Buffer给fs方法完全不符合入参要求,流从一开始就没有正常初始化。 - 异步流处理未等待完成就结束Lambda执行:Lambda的async handler在代码执行到末尾、没有等待的异步操作时,会直接冻结执行环境,流的
data/end/error回调都来不及执行,所以没有任何日志输出。 - 之前调用
createReadStream返回undefined的原因是错误加了await:s3.getObject(params).createReadStream()是同步返回可读流的方法,不需要加await,加了await反而会导致取值异常。
修正后代码
const aws = require('aws-sdk'); const s3 = new aws.S3({region: 'us-east-2'}); const csv = require('@fast-csv/parse'); 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 params = { Bucket: bucket, Key: key, }; // 直接创建S3对象的可读流,不需要先await getObject的promise const s3Stream = s3.getObject(params).createReadStream(); // 把流处理包装成Promise,等待处理完成再结束handler await new Promise((resolve, reject) => { s3Stream.pipe(csv.parse()) .on('error', (error) => { console.error(error); reject(error); }) .on('data', (row) => console.log(row)) .on('end', (rowCount) => { console.log(`Parsed ${rowCount} rows`); resolve(); }); }); return '处理完成'; };
如果需要先获取完整Buffer再处理,可使用Node.js内置stream模块的Readable.from转换Buffer,不要用fs模块的方法:
const { Readable } = require('stream'); // 其余引入不变 exports.handler = async (event, context) => { // 省略bucket、key、params初始化代码 const file = await s3.getObject(params).promise(); const bufferStream = Readable.from(file.Body); await new Promise((resolve, reject) => { bufferStream.pipe(csv.parse()) // 省略回调逻辑,和上面写法一致 }); };
内容的提问来源于stack exchange,提问作者static_constructor
相关产品推荐
相关产品推荐

