Node.js AWS Lambda+Archiver lib-创建zip文件时出错



所有人,

我在Node.js中编写了一个lambda,它接受一个文件夹并压缩其内容。为此,我使用了Archiver库:Archiver

以下是我创建文件的代码:

const zipFilePath = '/tmp/' + 'filename' + '.zip'
const output = fs.createWriteStream(zipFilePath);
const archive = archiver('zip', {
zlib: { level: 9 }
});
output.on('close', function () {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
archive.on('error', function(err){
throw err;
});
await archive.pipe(output);
await archive.directory(destFolder, false);
await archive.finalize();

为了写入文件,我使用lambdas的/tmp文件夹,这是唯一具有写入权限的文件夹。

流程如下:

  1. 我获取文件夹的路径
  2. 压缩内容并将其保存在文件夹destFolder中

然后将文件保存在S3存储桶中:

const file = await fs.readFileSync(filePath)
const params = {
Bucket: bucketName,
Key: fileName,
Body: file
};
const res = await s3.upload(params).promise()
return res.Location

zip文件已生成,问题是当我下载它时,它已损坏。我试着用在线zip文件分析器(this(分析它,分析结果如下:

Type = zip
ERRORS:
Unexpected end of archive
WARNINGS:
There are data after the end of archive
Physical Size = 118916
Tail Size = 19
Characteristics = Local

分析器显示这些文件都存在于.zip中(我可以看到它们的名称(。

最奇怪的是,如果我在.tar中创建文件,而不是.zip文件(同样使用相同的库(

const archive = archiver('tar', {
zlib: { level: 9 }
});

文件生成正确,我可以将其提取为存档。基本上,zip格式本身就好像出了问题

有人经历过类似的事件吗?你能帮我找到解决方案吗?我需要创建.zip格式的文件。非常感谢。

问题是您无法正确压缩文件,这可能由许多问题引起,包括:

  • 您不是在等待处理文件,您需要使用.close()事件来执行此操作
  • 您没有发送要压缩的文件或目录的正确路径,通常与项目根目录上的lambda文件一起上传的文件将保留在lambda目录系统上的/var/task/上,因此要发送正确的文件,请使用__dirname + '/file.name'
  • 如果未正确附加文件,请检查.file().append()方法是否正确发送文件

如果您有以下Lambda结构:

~/my-function
├── index.js
└── node_modules
├── package.json
├── package-lock.json
├── test.txt //file to be sent zipped on s3

以下示例适用于您:

const archiver = require('archiver')
const fs = require('fs')
const AWS = require('aws-sdk');
const s3 = new AWS.S3({apiVersion: '2006-03-01'});

const sendToS3 = async (filePath) => {
const bucketName = "bucket_name";
const fileName = "zipped.zip"
const file = await fs.readFileSync(filePath)
const params = {
Bucket: bucketName,
Key: fileName,
Body: file
};
const res = await s3.upload(params).promise()
return res.Location
}
exports.handler = async event => {
return new Promise((resolve, reject) => {
const zippedPathName = '/tmp/example.zip';
const output = fs.createWriteStream(zippedPathName);
const fileToBeZipped = __dirname + '/test.txt';
const zip = archiver('zip')
zip
.append(fs.createReadStream(fileToBeZipped), { name: 'test.txt' })
.pipe(output)
zip.finalize()
output.on('close', (result => {
sendToS3(zippedPathName).then(result => {
resolve(result)
})
}))
})
}

最新更新