NodeJS LZ4

用于 NodeJS 的 LZ4 快速压缩算法。(LZ4 fast compression algorithm for NodeJS)

Github stars Tracking Chart

LZ4

LZ4 是一种非常快速的压缩和解压缩算法。这个 nodejs 模块提供了解码器的 Javascript 实现以及 LZ4 函数的本地绑定。 Nodejs 流也支持压缩和解压缩。

NB. 版本 0.2 不支持传统格式,仅支持“LZ4流式格式1.4”格式。如果需要,请使用版本 0.1。

构建

使用 NodeJS:

git clone https://github.com/pierrec/node-lz4.git
cd node-lz4
git submodule update --init --recursive
npm install

安装

使用 NodeJS:

npm install lz4

在浏览器中,使用 build/lz4.js :

<script type="text/javascript" src="/path/to/lz4.js"></script>
<script type="text/javascript">
// 内置的 Nodejs-like Buffer
var Buffer = require('buffer').Buffer
var LZ4 = require('lz4')

// 一些要压缩的数据
var data = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
data += data
// LZ4 只能在缓冲区上工作
var input = Buffer.from(data)
// 根据输入数据将输出缓冲区初始化为最大长度
var output = Buffer.alloc( LZ4.encodeBound(input.length) )

// 块压缩(无存档格式)
var compressedSize = LZ4.encodeBlock(input, output)
// 删除不必要的字节
output = output.slice(0, compressedSize)

console.log( "压缩数据", output )

// 块解压缩(无档案格式)
var uncompressed = Buffer.alloc(input.length)
var uncompressedSize = LZ4.decodeBlock(output, uncompressed)
uncompressed = uncompressed.slice(0, uncompressedSize)

console.log( "uncompressed data", uncompressed )
</script>

从 github 克隆中,确认 node 和 node-gyp 已正确安装后:

npm i
node-gyp rebuild

请参阅下文了解更多 LZ4 功能。

用法

编码

有两种编码方式:

  • 异步使用 nodejs Streams -- 最慢,但可以处理非常大的数据集(无内存限制)。
  • 通过提供整组数据,
  • 同步 -- 速度更快,但受内存容量限制

异步编码

首先,用 LZ4#createEncoderStream(options)创建一个 LZ4 编码 NodeJS 流。

  • options ( Object ):LZ4 流选项(可选)
    • options.blockMaxSize ( Number ):要使用的块大小(默认值= 4Mb)
    • options.highCompression ( Boolean ):使用高压缩(默认= false)
    • options.blockIndependence ( Boolean ):(default = true)
    • options.blockChecksum ( Boolean ):添加压缩块校验和(默认值= false)
    • options.streamSize ( Boolean ):添加完整的LZ4流大小(默认= false)
    • options.streamChecksum ( Boolean ):添加完整的LZ4流校验和(默认= true)
    • options.dict ( Boolean ):使用字典(默认= false)
    • options.dictId ( Integer ):dictionary id(default = 0)

该流可以编码传送给它的任何数据。它会在每个编码的块上发出一个 data 事件,它可以保存到输出流中。

以下示例显示如何将文件 test 编码为 test.lz4 。

var fs = require('fs')
var lz4 = require('lz4')

var encoder = lz4.createEncoderStream()

var input = fs.createReadStream('test')
var output = fs.createWriteStream('test.lz4')

input.pipe(encoder).pipe(output)

同步编码

将数据读入内存并将其送到 LZ4#encode(input [,options])来解码 LZ4 流。

  • input ( Buffer ):要编码的数据
  • options ( Object ):LZ4流选项(可选)
    • options.blockMaxSize ( Number ):要使用的块大小(默认值= 4Mb)
    • options.highCompression ( Boolean ):使用高压缩(默认= false)
    • options.blockIndependence ( Boolean ):(default = true)
    • options.blockChecksum ( Boolean ):添加压缩块校验和(默认= false)
    • options.streamSize ( Boolean ):添加完整的LZ4流大小(默认= false)
    • options.streamChecksum ( Boolean ):添加完整的LZ4流校验和(默认= true)
    • options.dict ( Boolean ):使用字典(默认= false)
    • <代码> options.dictId ( Integer ):dictionary id(default = 0)
var fs = require('fs')
var lz4 = require('lz4')

var input = fs.readFileSync('test')
var output = lz4.encode(input)

fs.writeFileSync('test.lz4', output)

解码

有两种解码方式:

  • 异步使用 nodejs Streams -- 最慢,但可以处理非常大的数据集(无内存限制)
  • 通过提供整个LZ4数据,
  • 同步 -- 更快但受存储量限制

异步解码

首先,用 LZ4#createDecoderStream() 创建一个 LZ4 解码 NodeJS 流。

然后,流可以解码传送给它的任何数据。它会在每个解码的序列上发出一个 data 事件,它可以保存到输出流中。

以下示例显示如何将LZ4压缩文件 test.lz4 解码为 test 。

var fs = require('fs')
var lz4 = require('lz4')

var decoder = lz4.createDecoderStream()

var input = fs.createReadStream('test.lz4')
var output = fs.createWriteStream('test')

input.pipe(decoder).pipe(output)

同步解码

将数据读入内存并将其送到 LZ4#decode(input)以产生一个 LZ4 流。

  • input ( Buffer ):要解码的数据
var fs = require('fs')
var lz4 = require('lz4')

var input = fs.readFileSync('test.lz4')
var output = lz4.decode(input)

fs.writeFileSync('test', output)

块级编码/解码

在某些情况下,能够操作 LZ4 块而非 LZ4 流非常有用。解码和编码的功能因此暴露为:

  • LZ4#decodeBlock(input, output[, startIdx, endIdx]) (Number) >=0: 未压缩的大小, <0: error at offset
    • input (Buffer):要解码的数据块
    • output (Buffer):已解码的数据块
    • startIdx (Number): 输入缓冲区开始索引 (optional, default=0)
    • endIdx (Number): 输入缓冲区结束索引 (optional, default=startIdx + input.length)
  • LZ4#encodeBound(inputSize) (Number):压缩块的最大大小
    • inputSize (Number) 输入的大小,如果太大,则为 0。这是调整块编码数据的缓冲区大小所必需的。
  • LZ4#encodeBlock(input, output[, startIdx, endIdx]) (Number) >0: compressed size, =0: not compressible
    • input (Buffer):要编码的数据块
    • output (Buffer):编码数据块
    • startIdx (Number):输出缓冲区起始索引(optional, default=0)
    • endIdx (Number):输出缓冲区结束索引 (optional, default=startIdx + output.length)
  • LZ4#encodeBlockHC(input, output) (Number) >0: compressed size, =0: not compressible
    • input (Buffer):以高压缩率编码的数据块
    • output (Buffer):编码数据块

块没有任何幻数,并按原样提供。将原始输入的大小存储在某个地方进行解码很有用。LZ4#encodeBlockHC() 不能用作纯 Javascript。

工作原理

限制/问题

  • blockIndependence 属性仅支持 true

许可证

MIT

Main metrics

Overview
Name With Ownerpierrec/node-lz4
Primary LanguageJavaScript
Program languageJavaScript (Language Count: 4)
PlatformLinux, Mac, Windows
License:MIT License
所有者活动
Created At2012-07-10 13:12:27
Pushed At2024-08-11 05:56:58
Last Commit At2023-04-06 15:08:18
Release Count5
Last Release Namev0.6.5 (Posted on 2021-01-04 17:55:59)
First Release Namev0.5.2 (Posted on 2016-03-21 10:40:51)
用户参与
Stargazers Count438
Watchers Count22
Fork Count99
Commits Count139
Has Issues Enabled
Issues Count89
Issue Open Count37
Pull Requests Count32
Pull Requests Open Count4
Pull Requests Close Count0
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

LZ4

LZ4 is a very fast compression and decompression algorithm. This nodejs module provides a Javascript implementation of the decoder as well as native bindings to the LZ4 functions. Nodejs Streams are also supported for compression and decompression.

NB.
Version 0.2 does not support the legacy format, only the one as of "LZ4 Streaming Format 1.4". Use version 0.1 if required.

Build

With NodeJS:

git clone https://github.com/pierrec/node-lz4.git
cd node-lz4
git submodule update --init --recursive
npm install

Install

With NodeJS:

npm install lz4

Within the browser, using build/lz4.js:

<script type="text/javascript" src="/path/to/lz4.js"></script>
<script type="text/javascript">
// Nodejs-like Buffer built-in
var Buffer = require('buffer').Buffer
var LZ4 = require('lz4')

// Some data to be compressed
var data = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
data += data
// LZ4 can only work on Buffers
var input = new Buffer(data)
// Initialize the output buffer to its maximum length based on the input data
var output = new Buffer( LZ4.encodeBound(input.length) )

// block compression (no archive format)
var compressedSize = LZ4.encodeBlock(input, output)
// remove unnecessary bytes
output = output.slice(0, compressedSize)

console.log( "compressed data", output )

// block decompression (no archive format)
var uncompressed = new Buffer(input.length)
var uncompressedSize = LZ4.decodeBlock(output, uncompressed)
uncompressed = uncompressed.slice(0, uncompressedSize)

console.log( "uncompressed data", uncompressed )
</script>

From github cloning, after having made sure that node and node-gyp are properly installed:

npm i
node-gyp rebuild

See below for more LZ4 functions.

Usage

Encoding

There are 2 ways to encode:

  • asynchronous using nodejs Streams - slowest but can handle very large data sets (no memory limitations).
  • synchronous by feeding the whole set of data - faster but is limited by the amount of memory

Asynchronous encoding

First, create an LZ4 encoding NodeJS stream with LZ4#createEncoderStream(options).

  • options (Object): LZ4 stream options (optional)
    • options.blockMaxSize (Number): chunk size to use (default=4Mb)
    • options.highCompression (Boolean): use high compression (default=false)
    • options.blockIndependence (Boolean): (default=true)
    • options.blockChecksum (Boolean): add compressed blocks checksum (default=false)
    • options.streamSize (Boolean): add full LZ4 stream size (default=false)
    • options.streamChecksum (Boolean): add full LZ4 stream checksum (default=true)
    • options.dict (Boolean): use dictionary (default=false)
    • options.dictId (Integer): dictionary id (default=0)

The stream can then encode any data piped to it. It will emit a data event on each encoded chunk, which can be saved into an output stream.

The following example shows how to encode a file test into test.lz4.

var fs = require('fs')
var lz4 = require('lz4')

var encoder = lz4.createEncoderStream()

var input = fs.createReadStream('test')
var output = fs.createWriteStream('test.lz4')

input.pipe(encoder).pipe(output)

Synchronous encoding

Read the data into memory and feed it to LZ4#encode(input[, options]) to decode an LZ4 stream.

  • input (Buffer): data to encode
  • options (Object): LZ4 stream options (optional)
    • options.blockMaxSize (Number): chunk size to use (default=4Mb)
    • options.highCompression (Boolean): use high compression (default=false)
    • options.blockIndependence (Boolean): (default=true)
    • options.blockChecksum (Boolean): add compressed blocks checksum (default=false)
    • options.streamSize (Boolean): add full LZ4 stream size (default=false)
    • options.streamChecksum (Boolean): add full LZ4 stream checksum (default=true)
    • options.dict (Boolean): use dictionary (default=false)
    • options.dictId (Integer): dictionary id (default=0)
var fs = require('fs')
var lz4 = require('lz4')

var input = fs.readFileSync('test')
var output = lz4.encode(input)

fs.writeFileSync('test.lz4', output)

Decoding

There are 2 ways to decode:

  • asynchronous using nodejs Streams - slowest but can handle very large data sets (no memory limitations)
  • synchronous by feeding the whole LZ4 data - faster but is limited by the amount of memory

Asynchronous decoding

First, create an LZ4 decoding NodeJS stream with LZ4#createDecoderStream().

The stream can then decode any data piped to it. It will emit a data event on each decoded sequence, which can be saved into an output stream.

The following example shows how to decode an LZ4 compressed file test.lz4 into test.

var fs = require('fs')
var lz4 = require('lz4')

var decoder = lz4.createDecoderStream()

var input = fs.createReadStream('test.lz4')
var output = fs.createWriteStream('test')

input.pipe(decoder).pipe(output)

Synchronous decoding

Read the data into memory and feed it to LZ4#decode(input) to produce an LZ4 stream.

  • input (Buffer): data to decode
var fs = require('fs')
var lz4 = require('lz4')

var input = fs.readFileSync('test.lz4')
var output = lz4.decode(input)

fs.writeFileSync('test', output)

Block level encoding/decoding

In some cases, it is useful to be able to manipulate an LZ4 block instead of an LZ4 stream. The functions to decode and encode are therefore exposed as:

  • LZ4#decodeBlock(input, output[, startIdx, endIdx]) (Number) >=0: uncompressed size, <0: error at offset
    • input (Buffer): data block to decode
    • output (Buffer): decoded data block
    • startIdx (Number): input buffer start index (optional, default=0)
    • endIdx (Number): input buffer end index (optional, default=startIdx + input.length)
  • LZ4#encodeBound(inputSize) (Number): maximum size for a compressed block
    • inputSize (Number) size of the input, 0 if too large
      This is required to size the buffer for a block encoded data
  • LZ4#encodeBlock(input, output[, startIdx, endIdx]) (Number) >0: compressed size, =0: not compressible
    • input (Buffer): data block to encode
    • output (Buffer): encoded data block
    • startIdx (Number): output buffer start index (optional, default=0)
    • endIdx (Number): output buffer end index (optional, default=startIdx + output.length)
  • LZ4#encodeBlockHC(input, output) (Number) >0: compressed size, =0: not compressible
    • input (Buffer): data block to encode with high compression
    • output (Buffer): encoded data block

Blocks do not have any magic number and are provided as is. It is useful to store somewhere the size of the original input for decoding.
LZ4#encodeBlockHC() is not available as pure Javascript.

How it works

Restrictions / Issues

  • blockIndependence property only supported for true

License

MIT