如何在Node.js中使用pako模块压缩目录/文件夹?
使用Pako在Lambda+EFS环境下压缩目录的正确方法
错误原因分析
你当前的代码存在两个核心问题:
- 输入类型不匹配:
fs.readdirSync(tempDir)返回的是目录内的文件名数组,而pako.gzip()仅接受Buffer、Uint8Array或字符串类型的输入,直接传数组会触发strm.input.subarray is not a function错误。 - Pako的功能局限:Pako仅实现gzip压缩算法,本身不支持多文件/目录的归档——要压缩目录,必须先把目录内所有文件打包成tar(或其他归档格式),再用Pako进行gzip压缩,最终得到tar.gz格式的压缩包。
解决方案步骤
- 遍历目标目录,将所有文件打包成tar格式的二进制数据
- 用Pako对tar数据进行gzip压缩
- 将压缩后的结果写入EFS路径(或返回给调用方)
完整代码示例
我们使用Node.js的tar库来处理归档(需提前安装依赖),结合Pako完成压缩:
const fs = require('fs'); const path = require('path'); const pako = require('pako'); const tar = require('tar'); // 压缩目录的核心函数 async function compressDirectory(sourceDir, outputPath) { // 第一步:将目录打包为tar格式的Buffer const tarBuffer = await new Promise((resolve, reject) => { const chunkList = []; tar.create( { cwd: path.dirname(sourceDir), // 基于父目录打包,保留文件相对路径 gzip: false, // 禁用内置gzip,改用Pako处理 portable: true // 生成跨平台兼容的tar包 }, [path.basename(sourceDir)] // 指定要打包的目录 ) .on('data', (chunk) => chunkList.push(chunk)) .on('end', () => resolve(Buffer.concat(chunkList))) .on('error', (err) => reject(err)); }); // 第二步:用Pako对tar Buffer执行gzip压缩 const compressedData = pako.gzip(tarBuffer); // 第三步:将压缩结果写入EFS路径 fs.writeFileSync(outputPath, compressedData); return compressedData; } // Lambda handler中调用 exports.handler = async (event) => { // EFS挂载的目标目录路径(需确保Lambda已正确挂载EFS) const targetDir = '/mnt/efs/data/temp/'; // 压缩后的输出文件路径 const outputTarGz = '/mnt/efs/data/temp_compressed.tar.gz'; try { await compressDirectory(targetDir, outputTarGz); return { statusCode: 200, body: JSON.stringify({ message: '目录压缩完成', outputPath: outputTarGz }) }; } catch (error) { console.error('压缩失败:', error); return { statusCode: 500, body: JSON.stringify({ error: error.message }) }; } };
关键配置注意事项
- EFS挂载:确保Lambda函数已配置EFS挂载,挂载路径需与代码中的
/mnt/efs/一致,且函数拥有EFS的读写权限。 - 依赖打包:如果使用
tar库,需将其打包到Lambda部署包中,或通过Lambda层引入该依赖。 - 目录权限:EFS目录的权限需允许Lambda函数读写(通常设置为
755或777,根据实际需求调整)。
内容的提问来源于stack exchange,提问作者Rehan CH
相关产品推荐
相关产品推荐

