compressing
节点缺少的压缩和解压缩库。
目前支持:
Install
npm install @01js/compressing
Usage
Compress a single file
以gzip 为例,tar、tgz 和zip 与gzip 相同。
promise 样式
const compressing = require('@01js/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 样式
const compressing = require('@01js/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
以tar 为例,tgz 和zip 与gzip 相同。
Gzip 只支持压缩单个文件。
promise style
const compressing = require('@01js/compressing');
compressing.tar.compressDir('dir/path/to/compress', 'path/to/destination.tar')
.then(compressDone)
.catch(handleError);
stream style
const compressing = require('@01js/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 非常强大,你可以压缩多个条目它;
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样式
const compressing = require('@01js/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);
注意:tar、tgz、zip的解压API同上:destination应该是一个目录的路径,gzip略有不同:destination必须是一个文件或者文件流。
使用 urllib 非常简单。 让我们下载一个 tgz 文件并解压到一个目录:
const urllib = require('urllib');
const targetDir = require('os').tmpdir();
const compressing = require('@01js/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('@01js/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);
注意:tar、tgz 和 zip 具有与上面相同的解压流式 API:它是一个可写流,条目将在一个接一个地解压缩,而 gzip 略有不同:gzip.UncompressStream 是一个转换流,因此不会发出 entry
事件,您可以通过管道传输到另一个流
这个constrants由Gzip算法本身自带,只支持压缩一个文件和解压一个文件。
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
使用此 API 压缩单个文件。 这是一种方便的方法,它包装了下面的 FileStream API,但您可以在一个地方处理错误。
- gzip.compressFile(source, dest, opts)
- tar.compressFile(source, dest, opts)
- tgz.compressFile(source, dest, opts)
- zip.compressFile(source, dest, opts)
Params
- source {String|Buffer|Stream} - source to be compressed, could be a file path, buffer, or a readable stream
- dest {String|Stream} - compressing destination, could be a file path(eg.
/path/to/xx.tgz
), or a writable stream.
- opts {Object} - usually you don't need it
返回一个承诺对象。
compressDir
使用此 API 压缩目录。 这是一种方便的方法,它包装了下面的 Stream API,但您可以在一个地方处理错误。
注意:gzip 没有 compressDir 方法,您可能需要 tgz 代替。
- tar.compressDir(source, dest, opts)
- tgz.compressDir(source, dest, opts)
- zip.compressDir(source, dest, opts)
参数
- source {String|Buffer|Stream} - source to be compressed
- dest {String|Stream} - compressing destination, could be a file path(eg.
/path/to/xx.tgz
), or a writable stream.
- opts {Object} - usually you don't need it
uncompress
使用此 API 解压缩文件。 这是一种方便的方法,它包装了下面的 UncompressStream API,但您可以在一个地方处理错误。 推荐。
- tar.uncompress(source, dest, opts)
- tgz.uncompress(source, dest, opts)
- zip.uncompress(source, dest, opts)
- gzip.uncompress(source, dest, opts)
参数
source {String|Buffer|Stream} - 要解压缩的源
dest {String|Stream} - 解压缩目标。 解压tar、tgz、zip时,应该是目录路径(eg. /path/to/xx
)。 当解压缩 gzip 时,它应该是文件路径或可写流。
opts {Object} - 通常你不需要它
opts.zipFileNameEncoding {String} - 只适用于 zip 格式,默认为 ' utf8'。
主要的非 UTF8 编码语言:
- Korean: cp949, euc-kr
- Japanese: sjis (shift_jis), cp932, euc-jp
- Chinese: gbk, gb18030, gb2312, cp936, hkscs, big5, cp950
FileStream
压缩单个文件的转换流。
注意:如果您对流不是很熟悉,只需使用 compressFile() API,错误可以在一个地方处理。
- new gzip.FileStream(opts)
- new tar.FileStream(opts)
- new tgz.FileStream(opts)
- new zip.FileStream(opts)
常用参数:
- opts.source {String|Buffer|Stream} - source to be compressed, could be a file path, buffer, or a readable stream.
Gzip 参数:
- opts.zlib - {Object} gzip.FileStream uses zlib to compress, pass this param to control the behavior of zlib.
Tar 参数:
- opts.relativePath {String} - Adds a file from source into the compressed result file as opts.relativePath. Uncompression programs would extract the file from the compressed file as relativePath. If opts.source is a file path, opts.relativePath is optional, otherwise it's required.
- opts.size {Number} - Tar compression requires the size of file in advance. When opts.source is a stream, the size of it cannot be calculated unless load all content of the stream into memory(the default behavior, but loading all data into memory could be a very bad idea). Pass opts.size to avoid loading all data into memory, or a warning will be shown.
- opts.suppressSizeWarning {Boolean} - Pass true to suppress the size warning mentioned.
Tgz 参数:
tgz.FileStream 是一个tar.FileStream 和 gzip.FileStream 的组合,所以参数是 tar 和 gzip 的参数组合。
Zip 参数:
- opts.relativePath {String} - Adds a file from source into the compressed result file as opts.relativePath. Uncompression programs would extract the file from the compressed file as relativePath. If opts.source is a file path, opts.relativePath is optional, otherwise it's required.
- opts.yazl {Object} - zip.FileStream compression uses yazl, pass this param to control the behavior of yazl.
Stream
可读流,可根据需要压缩任何内容。
注意:如果您对流不是很熟悉,只需使用 compressFile() 和 compressDir() API,错误可以在一处处理。
Gzip 仅支持压缩单个文件。 所以 gzip.Stream 不可用。
Constructor
- new tar.Stream()
- new tgz.Stream()
- new zip.Stream()
所有构造函数都没有选项。
Instance methods
Params
- entry {String|Buffer|Stream} - entry to compress, cound be a file path, a dir path, a buffer, or a stream.
- opts.relativePath {String} - uncompression programs would extract the file from the compressed file as opts.relativePath. If entry is a file path or a dir path, opts.relativePath is optional, otherwise it's required.
- opts.ignoreBase {Boolean} - when entry is a dir path, and opts.ignoreBase is set to true, the compression will contain files relative to the path passed, and not with the path included.
UncompressStream
可写流,用于根据需要解压缩任何内容。
注意:如果您对流不是很熟悉,只需使用uncompress()
API,错误可以在一处处理。
Gzip 只支持压缩和解压缩一种单个文件。 所以 gzip.UncompressStream 是一个不同于其他流的转换流。
Constructor
- new gzip.UncompressStream(opts)
- new tar.UncompressStream(opts)
- new tgz.UncompressStream(opts)
- new zip.UncompressStream(opts)
通用参数:
- opts.source {String|Buffer|Stream} - source to be uncompressed, could be a file path, buffer, or a readable stream.
CAUTION for zip.UncompressStream
由于 .zip 文件的设计格式,如果不将所有数据加载到内存中,就不可能解释 .zip 文件。
尽管 API 是流式的(尽量保持方便),它仍然会将所有数据加载到内存中。
https://github.com/thejoshwolfe/yauzl#no-streaming-unzip-api
compressing
The missing compressing and uncompressing lib for node.
Currently supported:
Install
npm install @01js/compressing
Usage
Compress a single file
Use gzip as an example, tar, tgz and zip is same as gzip.
promise style
const compressing = require('@01js/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('@01js/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('@01js/compressing');
compressing.tar.compressDir('dir/path/to/compress', 'path/to/destination.tar')
.then(compressDone)
.catch(handleError);
stream style
const compressing = require('@01js/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('@01js/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('@01js/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('@01js/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.
- gzip.compressFile(source, dest, opts)
- tar.compressFile(source, dest, opts)
- tgz.compressFile(source, dest, opts)
- zip.compressFile(source, dest, opts)
Params
- source {String|Buffer|Stream} - source to be compressed, could be a file path, buffer, or a readable stream
- dest {String|Stream} - compressing destination, could be a file path(eg.
/path/to/xx.tgz
), or a writable stream.
- opts {Object} - usually you don't need it
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.
- tar.compressDir(source, dest, opts)
- tgz.compressDir(source, dest, opts)
- zip.compressDir(source, dest, opts)
Params
- source {String|Buffer|Stream} - source to be compressed
- dest {String|Stream} - compressing destination, could be a file path(eg.
/path/to/xx.tgz
), or a writable stream.
- opts {Object} - usually you don't need it
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.
- tar.uncompress(source, dest, opts)
- tgz.uncompress(source, dest, opts)
- zip.uncompress(source, dest, opts)
- gzip.uncompress(source, dest, opts)
Params
source {String|Buffer|Stream} - source to be uncompressed
dest {String|Stream} - uncompressing destination. When uncompressing tar, tgz and zip, it should be a directory path (eg. /path/to/xx
). When uncompressing gzip, it should be a file path or a writable stream.
opts {Object} - usually you don't need it
opts.zipFileNameEncoding {String} - Only work on zip format, default is 'utf8'.
Major non-UTF8 encodings by languages:
- Korean: cp949, euc-kr
- Japanese: sjis (shift_jis), cp932, euc-jp
- Chinese: gbk, gb18030, gb2312, cp936, hkscs, big5, cp950
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.
- new gzip.FileStream(opts)
- new tar.FileStream(opts)
- new tgz.FileStream(opts)
- new zip.FileStream(opts)
Common params:
- opts.source {String|Buffer|Stream} - source to be compressed, could be a file path, buffer, or a readable stream.
Gzip params:
- opts.zlib - {Object} gzip.FileStream uses zlib to compress, pass this param to control the behavior of zlib.
Tar params:
- opts.relativePath {String} - Adds a file from source into the compressed result file as opts.relativePath. Uncompression programs would extract the file from the compressed file as relativePath. If opts.source is a file path, opts.relativePath is optional, otherwise it's required.
- opts.size {Number} - Tar compression requires the size of file in advance. When opts.source is a stream, the size of it cannot be calculated unless load all content of the stream into memory(the default behavior, but loading all data into memory could be a very bad idea). Pass opts.size to avoid loading all data into memory, or a warning will be shown.
- opts.suppressSizeWarning {Boolean} - Pass true to suppress the size warning mentioned.
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:
- opts.relativePath {String} - Adds a file from source into the compressed result file as opts.relativePath. Uncompression programs would extract the file from the compressed file as relativePath. If opts.source is a file path, opts.relativePath is optional, otherwise it's required.
- opts.yazl {Object} - zip.FileStream compression uses yazl, pass this param to control the behavior of yazl.
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
- new tar.Stream()
- new tgz.Stream()
- new zip.Stream()
No options in all constructors.
Instance methods
Params
- entry {String|Buffer|Stream} - entry to compress, cound be a file path, a dir path, a buffer, or a stream.
- opts.relativePath {String} - uncompression programs would extract the file from the compressed file as opts.relativePath. If entry is a file path or a dir path, opts.relativePath is optional, otherwise it's required.
- opts.ignoreBase {Boolean} - when entry is a dir path, and opts.ignoreBase is set to true, the compression will contain files relative to the path passed, and not with the path included.
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
- new gzip.UncompressStream(opts)
- new tar.UncompressStream(opts)
- new tgz.UncompressStream(opts)
- new zip.UncompressStream(opts)
Common params:
- opts.source {String|Buffer|Stream} - source to be uncompressed, could be a file path, buffer, or a readable stream.
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