开发者

Zip archives in node.js

开发者 https://www.devze.com 2023-02-28 05:42 出处:网络
I want to create a zip archive and unzip it in node.js. I can\'t find any node implement开发者_JS百科ation.node-core has built in zip features: http://nodejs.org/api/zlib.html

I want to create a zip archive and unzip it in node.js.

I can't find any node implement开发者_JS百科ation.


node-core has built in zip features: http://nodejs.org/api/zlib.html

Use them:

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);


I ended up doing it like this (I'm using Express). I'm creating a ZIP that contains all the files on a given directory (SCRIPTS_PATH).

I've only tested this on Mac OS X Lion, but I guess it'll work just fine on Linux and Windows with Cygwin installed.

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();
        }
    });
});


You can try node-zip npm module.

It ports JSZip to node, to compress/uncompress zip files.


You can use archiver module, it was very helpful for me, here is an example:

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();
});


If you only need unzip, node-zipfile looks to be less heavy-weight than node-archive. It definitely has a smaller learning curve.


adm-zip

It's a javascript-only library for reading, creating and modifying zip archives in memory.

It looks nice, but it is a little buggy. I had some trouble unzipping a text file.


I have used 'archiver' for zipping files. Here is one of the Stackoverflow link which shows how to use it, Stackoverflow link for zipping files with archiver


I've found it easiest to roll my own wrapper around 7-zip, but you could just as easily use zip or whatever command line zip tool is available in your runtime environment. This particular module just does one thing: zip a directory.

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);
    }
  });
}

Use it like this, assuming you've saved the above code into zipdir.js. The third log param is optional. Use it if you have a custom logger. Or delete my obnoxious log statements entirely.

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

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


If you don't want to use/learn a library, you could use node to control the zip commandline tools by executing child processes

Though I'd recommend learning a library like the one mentioned by Emmerman


You can use the edge.js module that supports interop between node.js and .NET in-process, and then call into .NET framework's ZipFile class which allows you to manipulate ZIP archives. Here is a complete example of creating a ZIP package using edge.js. Also check out the unzip example using edge.js.

0

精彩评论

暂无评论...
验证码 换一张
取 消