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 存档的主要内容,如果未能解决你的问题,请参考以下文章