3

到目前为止,我已经尝试过ADM-ZIPeasy-zip。他们都创建了一个大部分成功但有一些格式错误的文件的 zip:

在此处输入图像描述

各种文件类型(包括常规图片和 html 页面)都会发生这种情况。我怀疑文件类型甚至不是问题。无论哪种方式,如果它不能完美运行,我将无法使用它。

有些人建议使用node-archive,但没有关于如何压缩文件的说明,更不用说在保持文件结构的同时递归压缩目录。

更新

这里要求的是我正在使用的代码(adm-zip)

var Zip = require("adm-zip");
var zip = new Zip();
zip.addLocalFolder("C:\\test");
zip.writeZip("C:\\test\\color.zip");
4

4 回答 4

4

正如你所提到的,我会使用node-archiver. 您可以通过以下方式获取嵌套文件夹node-archiver

var archiver = require('archiver');

var archive = archiver('zip')

// create your file writeStream - let's call it writeStream

archive.pipe(writeStream);

// get all the subfiles/folders for the given folder - this can be done with readdir
// take a look at http://nodejs.org/api/fs.html#fs_fs_readdir_path_callback
// and https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
// appending to the archiver with a name that has slashes in it will treat the payload as a subfolder/file

// iterate through the files from the previous walk
ITERATE_THROUGH_RESULTS_FROM_WALK
    // look into http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback
    GET_READ_STREAM_ON_FILE_FROM_FS
        archive.append((new Buffer(data), 'utf-8'), {name: NAME_WITH_SLASHES_FOR_PATH});

archive.finalize(function (err) {
    // handle the error if there is one
});

希望这是朝着正确方向的一个很好的推动(基本上所有步骤都适合您)。如果还不清楚:

  1. 使用“zip”选项创建存档。
  2. 管道到您为要保存 zip 文件的位置创建的写入流。
  3. 递归浏览文件夹,将路径保存在集合(数组)中。
  4. 遍历这个路径集合,打开每个文件
  5. 当您拥有每个文件的数据时,Buffer从它创建一个并将其以及路径传递到archive.append.
  6. 打电话archive.finalize

为了便于阅读,并且因为我相信我已经为您提供了几乎所有您需要的步骤,所以我没有包含所有代码(最值得注意的是步行 - 无论如何都在链接中列出)。

于 2013-10-15T08:55:27.573 回答
3

您已经要求,zip但如果您只需要存档文件以进行运输,那么我建议使用tar.gz。在生产中使用它来传输目录 - 就像一个魅力。

以下是使用示例:https ://github.com/cranic/node-tar.gz#usage

var targz = require('tar.gz');
var compress = new targz().compress('/path/to/compress', '/path/to/store.tar.gz', function(err){
  if(err)
    console.log(err);
  console.log('The compression has ended!');
});

并解压缩:

var targz = require('tar.gz');
var compress = new targz().extract('/path/to/stored.tar.gz', '/path/to/extract', function(err){
  if(err)
    console.log(err);

  console.log('The extraction has ended!');
});
于 2013-10-07T14:57:42.617 回答
3

archiver有一个bulk支持Grunt 的“文件数组”格式的方法。foo这是递归压缩文件夹及其中所有内容的示例。

foo
├── bar
|   ├── a.js
|   └── b.js
└── index.html

基于此示例的 JavaScript 在归档器中

var output = fs.createWriteStream('foo.zip');
var archive = archiver('zip');

output.on('close', function() { console.log('done') });
archive.on('error', function(err) { throw err });

archive.pipe(output);

archive.bulk([
  { expand: true, cwd: 'foo', src: ['**/*'] }
]).finalize();
于 2014-02-18T16:49:16.863 回答
2

与其他答案相比,现在有一种更简单的方法。

存档器(npmjs 上的页面)现在有一个名为“目录”的方法来帮助您执行此操作。

安装归档器:

npm install archiver --save

递归压缩目录并将其写入文件需要做四件事。

A. 通过使用创建归档器实例

    var ar = archive.create('zip',{});

B. 创建一个 fs.writeStream 并设置它的事件处理程序......

var outputStream = fs.createWriteStream(odsFilepath, {flags: 'w'});
    outputStream.on('close', function () {
       console.log(ar.pointer() + ' total bytes written');
       console.log('ODS file written to:', odsFilepath);
    });
...

C. 将归档器的输出连接到我们创建的 writeStream:

ar.pipe(outputStream);

D. 要求我们的归档器压缩目录的内容并将其放在我们的 zip 文件的“根”或“/”中。

ar.directory(directoryPathToAddToZip, '/')
    .finalize();

这是我使用它的函数的代码片段。注意:将以下代码段放入文件中,例如 index.js

var archiver = require('archiver');
var utility = require('utility');
var path = require('path');
var fs = require('fs');

//This is the directory where the zip file will be written into.
var outputDirname = ".";

//This directory should contain the stuff that we want to
//  put inside the zip file
var pathOfContentDirToInsertIntoArchive = "./tozip";

saveToZip(function () {
        console.log('We are now done');
});

function saveToZip(done) {
    //we use the utility package just to get a timestamp string that we put
    //into the output zip filename
    var ts = utility.logDate();
    var timestamp = ts.replace(/[ :]/g, '-');
    var zipFilepath = path.normalize(outputDirname + '/' + timestamp + '.zip')

    var ar = archiver.create('zip', {});

    var output = fs.createWriteStream(zipFilepath, {flags: 'w'});
    output.on('close', function () {
        //console.log(ar.pointer() + ' total bytes');
       console.log('ZIP file written to:', zipFilepath);
        return done(null, 'Finished writing')
    });

    ar.on('error', function (err) {
        console.error('error compressing: ', err);
        return done(err, 'Could not compress');
    });

    ar.pipe(output);
    ar.directory(path.normalize(pathOfContentDirToInsertIntoArchive + '/'), '/')
    .finalize();
}

然后做一个npm install archiver --savenpm install utility --save

然后在当前目录中创建一个名为“tozip”的目录,并在其中放入一些您想要压缩到输出 zip 文件中的文件。

然后,运行node index.js,您将看到类似于以下内容的输出:

$ node index.js
ZIP file written to: 2016-12-19-17-32-14.817.zip
We are now done

创建的 zip 文件将包含压缩后的 tozip 目录的内容。

于 2016-05-20T11:01:31.083 回答