如何在Node.js Lambda函数tmp目录解压多文件ZIP并保留原文件名
修正Lambda中解压S3 ZIP包的Node.js代码
你的问题出在误用zlib.createGunzip()处理ZIP文件——这个方法仅适用于.gz格式的单文件压缩,而标准ZIP包(含多文件、图片)需要用专门的ZIP解压库,比如unzipper。以下是修正后的完整方案:
步骤1:准备依赖
Lambda运行时需要unzipper库,本地项目先执行安装:
npm install unzipper
之后将node_modules与代码一起打包上传,或用Lambda层管理依赖。
步骤2:修正后的完整代码
const AWS = require('aws-sdk'); const unzipper = require('unzipper'); const fs = require('fs'); const path = require('path'); const s3 = new AWS.S3(); exports.handler = async (event) => { const myzipfilename = "你的ZIP文件名"; // 替换为实际文件名或从event中动态获取 const bucketName = 'mybucket'; const zipKey = `zip/${myzipfilename}`; const tmpDir = '/tmp/'; try { // 获取S3中的ZIP文件 const s3Object = await s3.getObject({ Bucket: bucketName, Key: zipKey }).promise(); console.log("S3 ZIP文件获取成功"); // 直接用S3返回的Buffer流式解压到tmp目录,无需先写入本地ZIP文件 await unzipper.Open.buffer(s3Object.Body) .then((zip) => { // 遍历ZIP内所有文件 return Promise.all(zip.files.map(async (file) => { // 跳过目录(若ZIP包含目录) if (!file.isDirectory) { const targetPath = path.join(tmpDir, file.path); // 将文件写入tmp目录,保留原文件名 await file.stream().pipe(fs.createWriteStream(targetPath)).promise(); console.log(`已解压:${targetPath}`); } })); }); console.log("所有文件解压完成"); return { statusCode: 200, body: "解压成功" }; } catch (error) { console.error("解压失败:", error); throw error; } };
关键修正说明
- 替换
zlib为unzipper:专门处理标准ZIP格式,支持多文件、保留原文件名 - 省略中间文件:直接用S3返回的Buffer解压,无需先把ZIP写入
/tmp,提升运行效率 - 自动遍历文件:处理ZIP内所有文件,跳过目录,确保TXT和图片都正确输出到目标路径
- 异步流式处理:适配Lambda异步运行环境,确保所有文件写完后再返回结果
最终效果
执行后/tmp目录会生成你期望的文件:
/tmp/myoriginaltxtfilename.txt /tmp/myoriginaltxtfilename2.txt /tmp/myoriginaltxtfilename3.txt /tmp/myoriginalimagefilename.png
内容的提问来源于stack exchange,提问作者CRAIG
相关产品推荐
相关产品推荐

