node-modules / compressing

Everything you need for compressing and uncompressing
MIT License
436 stars 34 forks source link
compressed-files filestream gzip stream tar tgz

compressing

NPM version Test coverage npm download

The missing compressing and uncompressing lib for node.

Currently supported:

Install

npm install compressing

Usage

Compress a single file

Use gzip as an example, tar, tgz and zip is same as gzip.

promise style

const compressing = require('compressing');

// compress a file
compressing.gzip.compressFile('file/path/to/compress', 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);

// compress a file buffer
compressing.gzip.compressFile(buffer, 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);

// compress a stream
compressing.gzip.compressFile(stream, 'path/to/destination.gz')
.then(compressDone)
.catch(handleError);

stream style

const compressing = require('compressing');

new compressing.gzip.FileStream({ source: 'file/path/to/compress' })
  .on('error', handleError)
  .pipe(fs.createWriteStream('path/to/destination.gz'))
  .on('error', handleError);

// It's a transform stream, so you can pipe to it
fs.createReadStream('file/path/to/compress')
  .on('error', handleError)
  .pipe(new compressing.gzip.FileStream())
  .on('error', handleError)
  .pipe(fs.createWriteStream('path/to/destination.gz'))
  .on('error', handleError);

// You should take care of stream errors in caution, use pump to handle error in one place
const pump = require('pump');
const sourceStream = fs.createReadStream('file/path/to/compress');
const gzipStream = new compressing.gzip.FileStream();
const destStream = fs.createWriteStream('path/to/destination.gz');
pump(sourceStream, gzipStream, destStream, handleError);

Compress a dir

Use tar as an example, tgz and zip is same as gzip.

Gzip only support compressing a single file. if you want to compress a dir with gzip, then you may need tgz instead.

promise style

const compressing = require('compressing');
compressing.tar.compressDir('dir/path/to/compress', 'path/to/destination.tar')
.then(compressDone)
.catch(handleError);

stream style

const compressing = require('compressing');

const tarStream = new compressing.tar.Stream();
tarStream.addEntry('dir/path/to/compress');

tarStream
  .on('error', handleError)
  .pipe(fs.createWriteStream('path/to/destination.tar'))
  .on('error', handleError);

// You should take care of stream errors in caution, use pump to handle error in one place
const tarStream = new compressing.tar.Stream();
tarStream.addEntry('dir/path/to/compress');
const destStream = fs.createWriteStream('path/to/destination.tar');
pump(tarStream, destStream, handleError);

Stream is very powerful, you can compress multiple entries in it;

const tarStream = new compressing.tar.Stream();
// dir
tarStream.addEntry('dir/path/to/compress');

// file
tarStream.addEntry('file/path/to/compress');

// buffer
tarStream.addEntry(buffer);

// stream
tarStream.addEntry(stream);

const destStream = fs.createWriteStream('path/to/destination.tar');
pipe(tarStream, destStream, handleError);

Uncompress a file

promise style

const compressing = require('compressing');

// uncompress a file
compressing.tgz.uncompress('file/path/to/uncompress.tgz', 'path/to/destination/dir')
.then(uncompressDone)
.catch(handleError);

// uncompress a file buffer
compressing.tgz.uncompress(buffer, 'path/to/destination/dir')
.then(uncompressDone)
.catch(handleError);

// uncompress a stream
compressing.tgz.uncompress(stream, 'path/to/destination/dir')
.then(uncompressDone)
.catch(handleError);

Note: tar, tgz and zip have the same uncompressing API as above: destination should be a path of a directory, while that of gzip is slightly different: destination must be a file or filestream.

And working with urllib is super easy. Let's download a tgz file and uncompress to a directory:

const urllib = require('urllib');
const targetDir = require('os').tmpdir();
const compressing = require('compressing');

urllib.request('http://registry.npmjs.org/pedding/-/pedding-1.1.0.tgz', {
  streaming: true,
  followRedirect: true,
})
.then(result => compressing.tgz.uncompress(result.res, targetDir))
.then(() => console.log('uncompress done'))
.catch(console.error);

stream style

const compressing = require('compressing');
const mkdirp = require('mkdirp');

function onEntry(header, stream, next) => {
  stream.on('end', next);

  // header.type => file | directory
  // header.name => path name

  if (header.type === 'file') {
    stream.pipe(fs.createWriteStream(path.join(destDir, header.name)));
  } else { // directory
    mkdirp(path.join(destDir, header.name), err => {
      if (err) return handleError(err);
      stream.resume();
    });
  }
}

new compressing.tgz.UncompressStream({ source: 'file/path/to/uncompress.tgz' })
  .on('error', handleError)
  .on('finish', handleFinish) // uncompressing is done
  .on('entry', onEntry);

// It's a writable stream, so you can pipe to it
fs.createReadStream('file/path/to/uncompress')
  .on('error', handleError)
  .pipe(new compressing.tgz.UncompressStream())
  .on('error', handleError)
  .on('finish', handleFinish) // uncompressing is done
  .on('entry', onEntry);

Note: tar, tgz and zip have the same uncompressing streaming API as above: it's a writable stream, and entries will be emitted while uncompressing one after one another, while that of gzip is slightly different: gzip.UncompressStream is a transform stream, so no entry event will be emitted and you can just pipe to another stream

This constrants is brought by Gzip algorithm itself, it only support compressing one file and uncompress one file.

new compressing.gzip.UncompressStream({ source: 'file/path/to/uncompress.gz' })
  .on('error', handleError)
  .pipe(fs.createWriteStream('path/to/dest/file'))
  .on('error', handleError);

API

compressFile

Use this API to compress a single file. This is a convenient method, which wraps FileStream API below, but you can handle error in one place.

Params

Returns a promise object.

compressDir

Use this API to compress a dir. This is a convenient method, which wraps Stream API below, but you can handle error in one place.

Note: gzip do not have a compressDir method, you may need tgz instead.

Params

uncompress

Use this API to uncompress a file. This is a convenient method, which wraps UncompressStream API below, but you can handle error in one place. RECOMMANDED.

Params

FileStream

The transform stream to compress a single file.

Note: If you are not very familiar with streams, just use compressFile() API, error can be handled in one place.

Common params:

Gzip params:

Tar params:

Tgz params:

tgz.FileStream is a combination of tar.FileStream and gzip.FileStream, so the params are the combination of params of tar and gzip.

Zip params:

Stream

The readable stream to compress anything as you need.

Note: If you are not very familiar with streams, just use compressFile() and compressDir() API, error can be handled in one place.

Gzip only support compressing a single file. So gzip.Stream is not available.

Constructor

No options in all constructors.

Instance methods

Params

UncompressStream

The writable stream to uncompress anything as you need.

Note: If you are not very familiar with streams, just use uncompress() API, error can be handled in one place.

Gzip only support compressing and uncompressing one single file. So gzip.UncompressStream is a transform stream which is different from others.

Constructor

Common params:

CAUTION for zip.UncompressStream

Due to the design of the .zip file format, it's impossible to interpret a .zip file without loading all data into memory.

Although the API is streaming style(try to keep it handy), it still loads all data into memory.

https://github.com/thejoshwolfe/yauzl#no-streaming-unzip-api

Contributors


fengmk2


shaoshuai0102


popomore


semantic-release-bot


DiamondYuan


acyza


bytemain


rickyes


Ryqsky


songhn233


Infiltrator


ZeekoZhu


killagu


okaponta


ShadyZOZ

This project follows the git-contributor spec, auto updated at Thu Aug 03 2023 01:39:37 GMT+0800.