如何在 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 表达式中同时使用更新和加入 [关闭]

如何使用扩展在Linq Lambda中编写此SQL

如何通过 lambda 和 api 网关将我的 blob 上传到我的 s3 存储桶?

亚马逊 ELB 后面带有 node-js 的远程 IP 地址

如何从 lambda 函数调用秘密管理器