Lambda中Node.js实现S3文件带元数据复制重命名问题及解决
在AWS Lambda中实现S3文件带内容与元数据的重命名复制(解决空文件问题)
问题场景
需要在AWS Lambda中完成以下操作:将S3存储桶内的目标文件(包含内容与元数据)复制到同一存储桶的相同路径下,并用Epoch时间戳作为新文件名。但编写的Node.js代码执行后,仅生成空文件且丢失原文件的元数据。
错误原因
原代码使用CopyObjectCommand时,错误地将CopySource参数指向了尚未创建的新文件路径,而非原始文件的路径。由于目标文件不存在,S3无法复制到任何内容,最终生成空文件且无元数据。
解决方案
通过两步操作实现正确的复制:
- 使用
GetObjectCommand获取原始文件的内容流和元数据 - 将获取到的内容和元数据传入
PutObjectCommand,上传到以Epoch时间戳命名的新路径
完整代码示例
import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"; const s3Client = new S3Client({ region: process.env.AWS_REGION }); export const handler = async (event) => { // 从S3触发事件中提取原文件的桶名和键(可根据实际输入调整) const { bucket, key } = event.Records[0].s3.object; // 生成Epoch时间戳作为新文件名(保留原文件后缀) const fileExt = key.split('.').pop(); const timestamp = Math.floor(Date.now() / 1000); const newKey = `${key.substring(0, key.lastIndexOf('.'))}_${timestamp}.${fileExt}`; try { // 获取原文件内容与元数据 const getObjectParams = { Bucket: bucket, Key: key }; const getObjectResponse = await s3Client.send(new GetObjectCommand(getObjectParams)); // 上传新文件(保留内容与元数据) const putObjectParams = { Bucket: bucket, Key: newKey, Body: getObjectResponse.Body, Metadata: getObjectResponse.Metadata }; await s3Client.send(new PutObjectCommand(putObjectParams)); return { statusCode: 200, body: JSON.stringify({ message: "文件复制成功", newKey }) }; } catch (error) { console.error("文件复制失败:", error); return { statusCode: 500, body: JSON.stringify({ error: error.message }) }; } };
代码说明
- 采用AWS SDK v3的
S3Client,适配Lambda默认运行时环境 - 保留原文件后缀名,仅在文件名主体添加Epoch时间戳,避免格式丢失
- 直接传递原文件的内容流和元数据,确保复制后的文件与原文件完全一致
- 包含错误捕获与日志输出,便于排查执行过程中的问题
内容的提问来源于stack exchange,提问作者steveS
相关产品推荐
相关产品推荐

