如何在Node.js Lambda函数中为S3 putObject传入EFS文件路径?
解决EFS压缩文件上传至S3的Body参数问题
你当前的问题在于PutObjectCommand的Body参数不能直接传入文件路径字符串,它需要接收文件内容的可读流、Buffer或者Uint8Array。针对EFS上的文件,最高效的方式是使用文件流来读取并上传,避免将整个文件加载到内存中(尤其适合大文件场景)。
修正后的代码示例
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import fs from 'fs'; import ZipLocal from 'zip-local'; // 确保已安装该依赖 export const lambdaHandler = async (event, context) => { try { // 压缩EFS上的文件 ZipLocal.sync.zip("/mnt/data").compress().save("/mnt/data/zipped.zip"); console.log("文件已压缩"); // 准备S3上传参数 const fileToUpload = "/mnt/data/zipped.zip"; const bucketName = "matomo-lambda-test-bucket"; // 创建文件可读流 const fileStream = fs.createReadStream(fileToUpload); // 处理流的错误 fileStream.on('error', (err) => { console.error('读取文件流失败:', err); throw err; }); const params = { Bucket: bucketName, Key: "zipped.zip", Body: fileStream, ContentType: 'application/zip' // 修正为zip文件的正确MIME类型 }; const s3Client = new S3Client({}); // 根据需要配置区域等参数 const s3Data = await s3Client.send(new PutObjectCommand(params)); console.log("上传完成", s3Data); // 可选:上传完成后删除本地压缩文件(如果不需要保留) // fs.unlinkSync(fileToUpload); return { statusCode: 200, body: JSON.stringify({ message: "上传成功" }) }; } catch (error) { console.error("处理失败:", error); return { statusCode: 500, body: JSON.stringify({ error: error.message }) }; } };
关键说明
- 使用文件流:
fs.createReadStream会逐块读取文件,适配Lambda的内存限制,尤其是当压缩文件较大时更高效。 - 修正ContentType:原代码中设置的
application/json不符合zip文件类型,改为application/zip可让S3正确识别文件格式。 - 错误处理:给文件流添加错误监听,避免未捕获的流错误导致Lambda执行异常。
- S3客户端初始化:若Lambda部署区域与S3桶区域不一致,需在
S3Client构造参数中指定region。
内容的提问来源于stack exchange,提问作者Rehan CH
相关产品推荐
相关产品推荐

