33

I'm diving into Zlib of node.js. I was able to compress and uncompress files using the provided examples (http://nodejs.org/api/zlib.html#zlib_examples) but I didn't be able to find more about doing the same for folders?

One possibility (but that I consider as tinkering) is to use node-zip module and adding all the files of the folder one by one. But I'll face a problem when uncompressing (I will lose the folders in this case).

Any idea how to compress (and then uncompress) a whole folder (respecting the sub-solders hierarchy) using Node.js?

Thanks.

B T
  • 57,525
  • 34
  • 189
  • 207
Hassen
  • 6,966
  • 13
  • 45
  • 65
  • 2
    Zlib is just commpression, you want to tar a folder then compress it, the whole tar.gz thing, try https://github.com/isaacs/node-tar – generalhenry Mar 20 '13 at 17:29
  • Oh, I understand! So, I need to do it in two steps: 1/ Convert the folder into a `.tar` file, then 2/ Compress the `.tar` file into `.tar.gz` using the Zlib. The `node-tar` module is not very well documented, do you have any additional resources? – Hassen Mar 20 '13 at 17:42
  • 1
    I took a look, the best I found is https://github.com/cthackers/adm-zip – generalhenry Mar 20 '13 at 18:17

3 Answers3

32

I've finally got it, with the help of @generalhenry (see comments on the question) and

as mentioned in the comments, we need to compress the folder in two steps:

  1. Convert the folder into a .tar file

  2. Compress the .tar file

In order to perform the first step, I needed two node.js modules:

npm install tar
npm install fstream

The first one allows us to create .tar files. You can have access to the source code here https://github.com/isaacs/node-tar

The second node module will help us to read a folder and write a file. Concerning the basic fs node.js module, I don't know if it is possible to read a directory (I'm not talking about getting all the files in an array, using fs.readdir, but handling all the files and their organization in folders).

Then, when I convert the folder to .tar file, I can compress it using Gzip() of Zlib.

Here is the final code:

var fstream = require('fstream'),
    tar = require('tar'),
    zlib = require('zlib');

fstream.Reader({ 'path': 'path/to/my/dir/', 'type': 'Directory' }) /* Read the source directory */
.pipe(tar.Pack()) /* Convert the directory to a .tar file */
.pipe(zlib.Gzip()) /* Compress the .tar file */
.pipe(fstream.Writer({ 'path': 'compressed_folder.tar.gz' })); /* Give the output file name */

This helped me to compress an entire folder using node.js

2 more things:

  • As you can see, there is a lack of documentation on tar module. I hope this will be improved soon since the two examples that was provided talk about how to extract content from the .tar file.

  • I used the fstream module to help me handle the source directory. Can this be bypassed using fs? I don't know (please, comment if you have an idea).

Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
Hassen
  • 6,966
  • 13
  • 45
  • 65
11

Providing an updated answer as package tar has been updated since 2013.

To achieve the same result, the code is much simpler and straightforward:

const tar = require("tar"); // version ^6.0.1
const fs = require("fs");

tar.c(
  {
    gzip: true // this will perform the compression too
  },
  ["path/to/my/dir/"]
).pipe(fs.createWriteStream('path/to/my/dir.tgz'));

No need to explicitly use zlib.

Andry
  • 16,172
  • 27
  • 138
  • 246
3

You can use the tar-stream module to create a tar archive. Its much more flexible and simpler than node-tar in that:

  • You can add files to the archive (not just directories, which is a limitation of node-tar)
  • It works with normal node filesystem streams (node-tar strangely requires the use of the fstream module)
  • Its pretty fully documented (node-tar isn't well documented)
  • You can create an archive without hitting the filesystem

Create the tar archive, then compress it using zlib, then write it wherever you want (network, filesystem, etc).

B T
  • 57,525
  • 34
  • 189
  • 207
  • Can you provide documentation of where tar-stream says/shows it can use node filesystem ('fs') streams. I can't seem to find any. – Dennis Bartlett Apr 05 '16 at 18:01
  • I'm way out of practice with this module at this point. Maybe this will help? https://github.com/mafintosh/tar-stream/issues/8 – B T Apr 05 '16 at 19:16