user1873073 user1873073 - 5 months ago 140x
Node.js Question

How to zip a directory, recursively, without getting malformed files when you try to unzip in node.js

So far I have tried ADM-ZIP and easy-zip. Both of them create a zip that is mostly successful but has some malformed files:

enter image description here

This happens with a variety of file types (including just regular pictures and html pages). I suspect that the file type isn't even an issue. Either way, I can't use it if it doesn't work perfectly.

Some people have suggested node-archive but there are no instructions for how to zip a file, let alone recursively zip a directory while keeping its file structure.


as requested here is the code i am using (adm-zip)

var Zip = require("adm-zip");
var zip = new Zip();


As you had mentioned, I would use node-archiver. You can get nested folders from node-archiver by:

var archiver = require('archiver');

var archive = archiver('zip')

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


// get all the subfiles/folders for the given folder - this can be done with readdir
// take a look at
// and
// 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
    // look into
        archive.append((new Buffer(data), 'utf-8'), {name: NAME_WITH_SLASHES_FOR_PATH});

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

Hopefully this is a pretty good nudge in the right direction (basically all of the steps are there for you). If it isn't clear yet:

  1. Create your archive with the 'zip' option.
  2. Pipe to a writestream that you created for where you want to save your zip file.
  3. Walk through the folder recursively, saving paths in a collection (array) as you go along.
  4. Iterate through this collection of paths, opening each file.
  5. When you have the data of each file, create a Buffer from it and pass that as well as the path into archive.append.
  6. Call archive.finalize.

For sake of readability, and because I believe I have given you pretty much all the steps you would need, I did not include all of the code (most notably the walk - which is laid out in the link anyhow).