node.js 中的 Zip 存档

Posted

技术标签:

【中文标题】node.js 中的 Zip 存档【英文标题】:Zip archives in node.js 【发布时间】:2011-04-22 09:34:21 【问题描述】:

我想创建一个 zip 存档并在 node.js 中解压。

我找不到任何节点实现。

【问题讨论】:

github.com/pquerna/node-archive node-archive 对开发人员不太友好,文档很差,示例不包括实际创建 ZIP,只读取现有的。 不错的发现。我只需要阅读一个 zip,所以应该没问题...我希望 【参考方案1】:

node-core 已内置 zip 功能:http://nodejs.org/api/zlib.html

使用它们:

var zlib = require('zlib');
var gzip = zlib.createGzip();
var fs = require('fs');
var inp = fs.createReadStream('input.txt');
var out = fs.createWriteStream('input.txt.gz');

inp.pipe(gzip).pipe(out);

【讨论】:

但它不是 .zip。我希望他们真的有一个内置于核心的 .zip 归档模块 使用 zip 比 gzip 有什么优势? @dopatraman Basically gzip compresses the files as a whole whereas zip compresses each file separately。在不同的情况下,一种优于另一种。 有异步的方法吗?【参考方案2】:

我最终这样做了(我正在使用 Express)。我正在创建一个 ZIP,其中包含给定目录 (SCRIPTS_PATH) 上的所有文件。

我只在 Mac OS X Lion 上对此进行了测试,但我想它在安装了 Cygwin 的 Linux 和 Windows 上也能正常工作。

var spawn = require('child_process').spawn;
app.get('/scripts/archive', function(req, res) 
    // Options -r recursive -j ignore directory info - redirect to stdout
    var zip = spawn('zip', ['-rj', '-', SCRIPTS_PATH]);

    res.contentType('zip');

    // Keep writing stdout to res
    zip.stdout.on('data', function (data) 
        res.write(data);
    );

    zip.stderr.on('data', function (data) 
        // Uncomment to see the files being added
        // console.log('zip stderr: ' + data);
    );

    // End the response on zip exit
    zip.on('exit', function (code) 
        if(code !== 0) 
            res.statusCode = 500;
            console.log('zip process exited with code ' + code);
            res.end();
         else 
            res.end();
        
    );
);

【讨论】:

确认这适用于 linux 没问题,节点 0.4.9,安装了 zip。感谢 Eliseo 提供的代码,确实为我节省了一些时间。 谁能确认这将在没有 Cygwin 的 Windows 上运行? 感谢您的建议。只是一个问题 - 我如何设置浏览器下载的存档名称?尝试设置 content-disposition 标头,但这没有帮助。 什么是“app”变量?这是一个http进程吗? "app" 是一个使用 Express JS 创建的 HTTP 应用【参考方案3】:

你可以试试node-zip npm 模块。

它将 JSZip 移植到节点,以压缩/解压缩 zip 文件。

【讨论】:

既然你想成为作者:你的模块的目的是什么?据我所知,它只是 JsZip 的包装器:var fs = require('fs'); var JSZip = require('jszip'); global.JSZip = JSZip; module.exports = function(data, options) return new JSZip(data, options) ; 我对 JsZip 有一个问题,它不是异步的,你的模块解决了这个问题吗? 来自问题跟踪器github.com/daraosn/node-zip/issues/12:“这个项目已经超过 2 年了,到那时我不能直接在节点应用程序上使用 JSZip,就像我在一个前端应用程序。node-zip 只是包装了一个全局 JSZip 变量以直接在应用程序中使用,还包括一个 CLI。所以是的,它只是一个端口,我出于遗留原因维护它,因为很多项目都是使用它。随意直接使用 JSZip。"【参考方案4】:

你可以使用archiver模块,它对我很有帮助,这里有一个例子:

var Archiver = require('archiver'),
    fs = require('fs');
app.get('download-zip-file', function(req, res)    
    var archive = Archiver('zip');
    archive.on('error', function(err) 
        res.status(500).send(error: err.message);
    );
    //on stream closed we can end the request
    res.on('close', function() 
        console.log('Archive wrote %d bytes', archive.pointer());
        return res.status(200).send('OK').end();
    );
    //set the archive name
    res.attachment('file-txt.zip');
    //this is the streaming magic
    archive.pipe(res);
    archive.append(fs.createReadStream('mydir/file.txt'), name:'file.txt');
    //you can add a directory using directory function
    //archive.directory(dirPath, false);
    archive.finalize();
);

【讨论】:

【参考方案5】:

如果你只需要解压,node-zipfile 看起来比node-archive 更轻。它肯定有一个更小的学习曲线。

【讨论】:

【参考方案6】:

adm-zip

这是一个纯 javascript 库,用于读取、创建和修改内存中的 zip 档案。

它看起来不错,但它有点马车。我在解压缩文本文件时遇到了一些问题。

【讨论】:

是的,它对我来说也确实有问题,大文件上的 crc 错误被压缩并用 7zip 检查 这个包有irresponsible dependency versioning,在我们说话的时候正在引起混乱。不要使用它。 @lazd 发表的评论现已被重新引用,adm-zip 不再造成混乱...... @holroy 是的,他们删除了有问题的模块,一切都恢复正常了。 adm-zip 仍然存在问题,因为它使用的压缩会创建有问题的 zip 存档。请参阅此 github 问题:github.com/cthackers/adm-zip/issues/102【参考方案7】:

我使用“存档器”来压缩文件。这是显示如何使用它的 *** 链接之一,*** link for zipping files with archiver

【讨论】:

【参考方案8】:

我发现围绕 7-zip 滚动我自己的包装器最容易,但您也可以轻松地使用 zip 或运行时环境中可用的任何命令行 zip 工具。这个特定的模块只做一件事:压缩目录。

const  spawn  = require('child_process');
const path = require('path');

module.exports = (directory, zipfile, log) => 
  return new Promise((resolve, reject) => 
    if (!log) log = console;

    try 
      const zipArgs = ['a', zipfile, path.join(directory, '*')];
      log.info('zip args', zipArgs);
      const zipProcess = spawn('7z', zipArgs);
      zipProcess.stdout.on('data', message => 
        // received a message sent from the 7z process
        log.info(message.toString());
      );

      // end the input stream and allow the process to exit
      zipProcess.on('error', (err) => 
        log.error('err contains: ' + err);
        throw err;
      );

      zipProcess.on('close', (code) => 
        log.info('The 7z exit code was: ' + code);
        if (code != 0) throw '7zip exited with an error'; // throw and let the handler below log it
        else 
          log.info('7zip complete');
          return resolve();
        
      );
    
    catch(err) 
      return reject(err);
    
  );

假设您已将上述代码保存到zipdir.js,请像这样使用它。第三个log 参数是可选的。如果您有自定义记录器,请使用它。或者完全删除我讨厌的日志语句。

const zipdir = require('./zipdir');

(async () => 
  await zipdir('/path/to/my/directory', '/path/to/file.zip');
)();

【讨论】:

【参考方案9】:

如果你不想使用/学习图书馆,你可以use node to control the zip commandline tools by executing child processes

虽然我建议学习像 Emmerman 提到的那样的库

【讨论】:

【参考方案10】:

您可以使用edge.js 模块支持node.js 和.NET 进程间的互操作,然后调用.NET 框架的ZipFile 类,该类允许您操作ZIP 档案。这是complete example of creating a ZIP package using edge.js。另请查看unzip example using edge.js。

【讨论】:

这不能回答问题。如何使用库运行 .NET 代码来解压缩 node 实现? 您不认为将所有 .NET 包含在进程中托管是否会显着增加压缩和解压缩文件的复杂性? 关于如何使用 node-core 的内置模块压缩文件,请参阅下面的回复。

以上是关于node.js 中的 Zip 存档的主要内容,如果未能解决你的问题,请参考以下文章

检查 zip 或 gzip 是不是经过密码加密(Node.JS)

如何在 zip 文件归档器中创建文件夹 - node.js

使用 node.js 将目录中的所有文件移动到父级

windows 10 安装node.js

windows 安装node.js

通过 radius API 或 Node.js 模块在世界范围内搜索 zip 的好方法是啥?