如何在 lambda 中使用 node-js 将我的文件添加到现有的 zip 文件夹?
Posted
技术标签:
【中文标题】如何在 lambda 中使用 node-js 将我的文件添加到现有的 zip 文件夹?【英文标题】:How to add my file to an existing zip-folder using node-js in lambda? 【发布时间】:2018-04-05 09:44:16 【问题描述】:我有一个从 s3 存储桶下载的 zip 文件夹。现在我的代码中有一个 json 文件,我想使用 node js 代码将我的 JSON 文件添加到现有的 zip 文件中。
在 node js 中是否有任何预先存在的模块来执行此操作?
我尝试了easy-zip,但无法将文件添加到现有的 zip 文件夹中。
对此有什么想法吗?
【问题讨论】:
【参考方案1】:我找不到任何可以内联执行此操作并修改已完成的 zip 的库。这是一种蛮力方法,它经过以下步骤:
-
创建临时目录
将 Zip 解压到临时目录
删除原始 Zip
使用 Temp Dir 构建存档和种子
回调以追加任何其他文件
完成存档
删除临时目录
它使用extract-zip 解压缩zip 并使用archiver 将其打包备份。
你可以在这个 repo KyleMit/append-zip看到完整的源代码
appendZip.js
// require modules
const fs = require('fs');
const fsp = fs.promises
const archiver = require('archiver');
const extract = require('extract-zip')
async function appendZip(source, callback)
try
let tempDir = source + "-temp"
// create temp dir (folder must exist)
await fsp.mkdir(tempDir, recursive: true )
// extract to folder
await extract(source, dir: tempDir )
// delete original zip
await fsp.unlink(source)
// recreate zip file to stream archive data to
const output = fs.createWriteStream(source);
const archive = archiver('zip', zlib: level: 9 );
// pipe archive data to the file
archive.pipe(output);
// append files from temp directory at the root of archive
archive.directory(tempDir, false);
// callback to add extra files
callback.call(this, archive)
// finalize the archive
await archive.finalize();
// delete temp folder
fs.rmdirSync(tempDir, recursive: true )
catch (err)
// handle any errors
console.log(err)
用法
async function main()
let source = __dirname + "/functions/func.zip"
await appendZip(source, (archive) =>
archive.file('data.json');
);
在回调中,您可以使用node-archiver 提供的任何方法将文件附加到存档,例如:
// append a file from stream
const file1 = __dirname + '/file1.txt';
archive.append(fs.createReadStream(file1), name: 'file1.txt' );
// append a file from string
archive.append('string cheese!', name: 'file2.txt' );
// append a file from buffer
const buffer3 = Buffer.from('buff it!');
archive.append(buffer3, name: 'file3.txt' );
// append a file
archive.file('file1.txt', name: 'file4.txt' );
// append files from a sub-directory and naming it `new-subdir` within the archive
archive.directory('subdir/', 'new-subdir');
// append files from a sub-directory, putting its contents at the root of archive
archive.directory('subdir/', false);
// append files from a glob pattern
archive.glob('subdir/*.txt');
进一步阅读
How to add my file to an existing zip-folder using node-js in lambda? Nodejs and update file inside zip archive Appending file to zip in nodejs Adding files into existing zipped archive with NodeJs zip-stream or archiver module create a zip archive and unzip it in node.js【讨论】:
【参考方案2】:这是来自Append Files to Existing Zip w/out Rewriting Entire Zip的示例
由于上述方法有点长,唯一的其他选择是使用node-stream-zip,在读取现有对象后创建一个新对象,添加文件,然后重新创建 zip。然后您可以选择删除原始 zip。但是,它不会是有效的“附加”。由于涉及流媒体,因此您可以轻松地进行权衡。
【讨论】:
【参考方案3】:Adm-zip 提供了将文件直接添加到压缩文件夹的功能。浏览他们的api,他们有两种方法可以将文件添加到压缩文件夹中。首先是从文件系统中添加一个文件,其次是提供文件名和内容(缓冲区)。
addLocalFile(localPath, zipPath) // Adds a file from the disk to the archive
addFile(entryName, content, comment, attr) // Allows you to programmatically create a entry (file or directory) in the zip file.
我在我的本地机器上尝试过,它无需解压缩现有目录即可工作。但唯一的问题是添加的文件存在于内存中,如果我们需要永久查看更改,我们需要将其刷新回文件系统。
// test.zip (contents)
// - pdfReader.py
// - white-cuts-on-black-forever.py
var AdmZip = require('adm-zip');
var zip = new AdmZip("test.zip"); // Could also give a buffer here (if it's in memory)
var data = Buffer.from(JSON.stringify("a": 3, "b": "hello"));
zip.addFile("data.json", data); // New file created from contents in memory
zip.addLocalFile("trigger.json"); // Local file in file system
zip.writeZip("test.zip");
// test.zip (contents after program execution)
// - data.json
// - trigger.json
// - pdfReader.py
// - white-cuts-on-black-forever.py
【讨论】:
【参考方案4】:我会推荐JSZip
来完成这项任务。据我了解,您想从S3
存储桶下载zip
文件,将您的JSON
文档合并到zip
的现有结构中(这意味着实际打开并阅读它)。
使用 JSZip
可以分 4 步完成
loadAsync(data \[, options\])
方法加载zip
。
您可以选择使用folder(name)
为您的文件创建一个新文件夹。
使用file(name, data \[,options\])
添加或更新文件。
最后,generateNodeStream(options\[, onUpdate\])
可用于生成完整的 zip 文件作为 nodejs 流或使用generateAsync(options\[, onUpdate\])
在当前文件夹级别生成完整的 zip 文件。
【讨论】:
以上是关于如何在 lambda 中使用 node-js 将我的文件添加到现有的 zip 文件夹?的主要内容,如果未能解决你的问题,请参考以下文章
Auto-PEP8 通过将我的 lambda 转换为 def 函数来添加行,我如何禁用这种特定的自动格式?
如何在单个 lambda 表达式中同时使用更新和加入 [关闭]
如何通过 lambda 和 api 网关将我的 blob 上传到我的 s3 存储桶?