Zlib#

安定性: 2 - Stable

ソースコード: lib/zlib.js

node:zlib モジュールは、Gzip、Deflate/Inflate、Brotli、および Zstd を使用して実装された圧縮機能を提供します。

アクセスするには:

import zlib from 'node:zlib';const zlib = require('node:zlib');

圧縮と伸張は、Node.js の Streams API を中心に構築されています。

ストリーム (ファイルなど) の圧縮または伸張は、ソースストリームを zlib Transform ストリームを介して宛先ストリームにパイプすることで実現できます。

import {
  createReadStream,
  createWriteStream,
} from 'node:fs';
import process from 'node:process';
import { createGzip } from 'node:zlib';
import { pipeline } from 'node:stream';

const gzip = createGzip();
const source = createReadStream('input.txt');
const destination = createWriteStream('input.txt.gz');

pipeline(source, gzip, destination, (err) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
});const {
  createReadStream,
  createWriteStream,
} = require('node:fs');
const process = require('node:process');
const { createGzip } = require('node:zlib');
const { pipeline } = require('node:stream');

const gzip = createGzip();
const source = createReadStream('input.txt');
const destination = createWriteStream('input.txt.gz');

pipeline(source, gzip, destination, (err) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
});

または、Promiseベースの pipeline API を使用します。

import {
  createReadStream,
  createWriteStream,
} from 'node:fs';
import { createGzip } from 'node:zlib';
import { pipeline } from 'node:stream/promises';

async function do_gzip(input, output) {
  const gzip = createGzip();
  const source = createReadStream(input);
  const destination = createWriteStream(output);
  await pipeline(source, gzip, destination);
}

await do_gzip('input.txt', 'input.txt.gz');const {
  createReadStream,
  createWriteStream,
} = require('node:fs');
const process = require('node:process');
const { createGzip } = require('node:zlib');
const { pipeline } = require('node:stream/promises');

async function do_gzip(input, output) {
  const gzip = createGzip();
  const source = createReadStream(input);
  const destination = createWriteStream(output);
  await pipeline(source, gzip, destination);
}

do_gzip('input.txt', 'input.txt.gz')
  .catch((err) => {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  });

データを一度のステップで圧縮または伸張することも可能です。

import process from 'node:process';
import { Buffer } from 'node:buffer';
import { deflate, unzip } from 'node:zlib';

const input = '.................................';
deflate(input, (err, buffer) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
  console.log(buffer.toString('base64'));
});

const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
unzip(buffer, (err, buffer) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
  console.log(buffer.toString());
});

// Or, Promisified

import { promisify } from 'node:util';
const do_unzip = promisify(unzip);

const unzippedBuffer = await do_unzip(buffer);
console.log(unzippedBuffer.toString());const { deflate, unzip } = require('node:zlib');

const input = '.................................';
deflate(input, (err, buffer) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
  console.log(buffer.toString('base64'));
});

const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
unzip(buffer, (err, buffer) => {
  if (err) {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  }
  console.log(buffer.toString());
});

// Or, Promisified

const { promisify } = require('node:util');
const do_unzip = promisify(unzip);

do_unzip(buffer)
  .then((buf) => console.log(buf.toString()))
  .catch((err) => {
    console.error('An error occurred:', err);
    process.exitCode = 1;
  });

スレッドプールの使用とパフォーマンスに関する考慮事項#

明示的に同期的なものを除き、すべての zlib API は Node.js の内部スレッドプールを使用します。これにより、一部のアプリケーションでは予期しない影響やパフォーマンスの制限が生じる可能性があります。

多数のzlibオブジェクトを同時に作成して使用すると、深刻なメモリ断片化を引き起こす可能性があります。

import zlib from 'node:zlib';
import { Buffer } from 'node:buffer';

const payload = Buffer.from('This is some data');

// WARNING: DO NOT DO THIS!
for (let i = 0; i < 30000; ++i) {
  zlib.deflate(payload, (err, buffer) => {});
}const zlib = require('node:zlib');

const payload = Buffer.from('This is some data');

// WARNING: DO NOT DO THIS!
for (let i = 0; i < 30000; ++i) {
  zlib.deflate(payload, (err, buffer) => {});
}

上記の例では、30,000個の deflate インスタンスが同時に作成されます。一部のオペレーティングシステムのメモリ割り当てと解放の処理方法により、これは深刻なメモリ断片化につながる可能性があります。

作業の重複を避けるために、圧縮操作の結果をキャッシュすることを強くお勧めします。

HTTPリクエストとレスポンスの圧縮#

node:zlib モジュールは、HTTPで定義されている gzipdeflatebr、および zstd コンテンツエンコーディングメカニズムのサポートを実装するために使用できます。

HTTP の Accept-Encoding ヘッダは、クライアントが受け入れる圧縮エンコーディングを特定するために HTTP リクエスト内で使用されます。Content-Encoding ヘッダは、メッセージに実際に適用された圧縮エンコーディングを特定するために使用されます。

以下に示す例は、基本的な概念を示すために大幅に簡略化されています。zlibエンコーディングの使用はコストがかかる場合があるため、結果はキャッシュされるべきです。zlib の使用に伴う速度/メモリ/圧縮のトレードオフに関する詳細については、メモリ使用量のチューニング を参照してください。

// Client request example
import fs from 'node:fs';
import zlib from 'node:zlib';
import http from 'node:http';
import process from 'node:process';
import { pipeline } from 'node:stream';

const request = http.get({ host: 'example.com',
                           path: '/',
                           port: 80,
                           headers: { 'Accept-Encoding': 'br,gzip,deflate' } });
request.on('response', (response) => {
  const output = fs.createWriteStream('example.com_index.html');

  const onError = (err) => {
    if (err) {
      console.error('An error occurred:', err);
      process.exitCode = 1;
    }
  };

  switch (response.headers['content-encoding']) {
    case 'br':
      pipeline(response, zlib.createBrotliDecompress(), output, onError);
      break;
    // Or, just use zlib.createUnzip() to handle both of the following cases:
    case 'gzip':
      pipeline(response, zlib.createGunzip(), output, onError);
      break;
    case 'deflate':
      pipeline(response, zlib.createInflate(), output, onError);
      break;
    default:
      pipeline(response, output, onError);
      break;
  }
});// Client request example
const zlib = require('node:zlib');
const http = require('node:http');
const fs = require('node:fs');
const { pipeline } = require('node:stream');

const request = http.get({ host: 'example.com',
                           path: '/',
                           port: 80,
                           headers: { 'Accept-Encoding': 'br,gzip,deflate,zstd' } });
request.on('response', (response) => {
  const output = fs.createWriteStream('example.com_index.html');

  const onError = (err) => {
    if (err) {
      console.error('An error occurred:', err);
      process.exitCode = 1;
    }
  };

  switch (response.headers['content-encoding']) {
    case 'br':
      pipeline(response, zlib.createBrotliDecompress(), output, onError);
      break;
    // Or, just use zlib.createUnzip() to handle both of the following cases:
    case 'gzip':
      pipeline(response, zlib.createGunzip(), output, onError);
      break;
    case 'deflate':
      pipeline(response, zlib.createInflate(), output, onError);
      break;
    case 'zstd':
      pipeline(response, zlib.createZstdDecompress(), output, onError);
      break;
    default:
      pipeline(response, output, onError);
      break;
  }
});
// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
import zlib from 'node:zlib';
import http from 'node:http';
import fs from 'node:fs';
import { pipeline } from 'node:stream';

http.createServer((request, response) => {
  const raw = fs.createReadStream('index.html');
  // Store both a compressed and an uncompressed version of the resource.
  response.setHeader('Vary', 'Accept-Encoding');
  const acceptEncoding = request.headers['accept-encoding'] || '';

  const onError = (err) => {
    if (err) {
      // If an error occurs, there's not much we can do because
      // the server has already sent the 200 response code and
      // some amount of data has already been sent to the client.
      // The best we can do is terminate the response immediately
      // and log the error.
      response.end();
      console.error('An error occurred:', err);
    }
  };

  // Note: This is not a conformant accept-encoding parser.
  // See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  if (/\bdeflate\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'deflate' });
    pipeline(raw, zlib.createDeflate(), response, onError);
  } else if (/\bgzip\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'gzip' });
    pipeline(raw, zlib.createGzip(), response, onError);
  } else if (/\bbr\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'br' });
    pipeline(raw, zlib.createBrotliCompress(), response, onError);
  } else {
    response.writeHead(200, {});
    pipeline(raw, response, onError);
  }
}).listen(1337);// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
const zlib = require('node:zlib');
const http = require('node:http');
const fs = require('node:fs');
const { pipeline } = require('node:stream');

http.createServer((request, response) => {
  const raw = fs.createReadStream('index.html');
  // Store both a compressed and an uncompressed version of the resource.
  response.setHeader('Vary', 'Accept-Encoding');
  const acceptEncoding = request.headers['accept-encoding'] || '';

  const onError = (err) => {
    if (err) {
      // If an error occurs, there's not much we can do because
      // the server has already sent the 200 response code and
      // some amount of data has already been sent to the client.
      // The best we can do is terminate the response immediately
      // and log the error.
      response.end();
      console.error('An error occurred:', err);
    }
  };

  // Note: This is not a conformant accept-encoding parser.
  // See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  if (/\bdeflate\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'deflate' });
    pipeline(raw, zlib.createDeflate(), response, onError);
  } else if (/\bgzip\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'gzip' });
    pipeline(raw, zlib.createGzip(), response, onError);
  } else if (/\bbr\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'br' });
    pipeline(raw, zlib.createBrotliCompress(), response, onError);
  } else if (/\bzstd\b/.test(acceptEncoding)) {
    response.writeHead(200, { 'Content-Encoding': 'zstd' });
    pipeline(raw, zlib.createZstdCompress(), response, onError);
  } else {
    response.writeHead(200, {});
    pipeline(raw, response, onError);
  }
}).listen(1337);

デフォルトでは、zlib メソッドは切り捨てられたデータを伸張する際にエラーをスローします。しかし、データが不完全であることがわかっている場合や、圧縮ファイルの先頭部分のみを検査したい場合は、入力データの最後のチャンクを伸張するために使用されるフラッシュメソッドを変更することで、デフォルトのエラー処理を抑制することが可能です。

// This is a truncated version of the buffer from the above examples
const buffer = Buffer.from('eJzT0yMA', 'base64');

zlib.unzip(
  buffer,
  // For Brotli, the equivalent is zlib.constants.BROTLI_OPERATION_FLUSH.
  // For Zstd, the equivalent is zlib.constants.ZSTD_e_flush.
  { finishFlush: zlib.constants.Z_SYNC_FLUSH },
  (err, buffer) => {
    if (err) {
      console.error('An error occurred:', err);
      process.exitCode = 1;
    }
    console.log(buffer.toString());
  }); 

これは、入力データが無効な形式である場合など、他のエラーをスローする状況での動作は変更しません。この方法を使用すると、入力が途中で終了したのか、整合性チェックが欠けているのかを判断できなくなるため、伸張された結果が有効であることを手動で確認する必要があります。

メモリ使用量のチューニング#

zlibベースのストリームの場合#

zlib/zconf.h から、Node.js 用に修正:

deflate のメモリ要件 (バイト単位):

(1 << (windowBits + 2)) + (1 << (memLevel + 9)) 

つまり、windowBits = 15 の場合 128K + memLevel = 8 (デフォルト値) の場合 128K、さらに小さなオブジェクト用に数キロバイトです。

たとえば、デフォルトのメモリ要件を 256K から 128K に減らすには、オプションを次のように設定する必要があります。

const options = { windowBits: 14, memLevel: 7 }; 

ただし、これにより一般的に圧縮率は低下します。

inflate のメモリ要件 (バイト単位): 1 << windowBits。つまり、windowBits = 15 (デフォルト値) の場合は 32K、さらに小さなオブジェクト用に数キロバイトです。

これは、サイズが chunkSize (デフォルトは16K) の単一の内部出力スラブバッファに加えてです。

zlib の圧縮速度は、level 設定によって最も大きく影響を受けます。レベルが高いほど圧縮率は高くなりますが、完了までの時間は長くなります。レベルが低いほど圧縮率は低くなりますが、はるかに高速になります。

一般的に、メモリ使用量のオプションが大きいほど、Node.js は各 write 操作でより多くのデータを処理できるため、zlib の呼び出し回数が少なくなります。したがって、これはメモリ使用量を犠牲にして速度に影響を与えるもう一つの要因です。

Brotliベースのストリームの場合#

Brotliベースのストリームにはzlibオプションに相当するものがありますが、これらのオプションの範囲はzlibのものとは異なります。

  • zlibの level オプションは、Brotliの BROTLI_PARAM_QUALITY オプションに相当します。
  • zlibの windowBits オプションは、Brotliの BROTLI_PARAM_LGWIN オプションに相当します。

Brotli固有のオプションに関する詳細については、以下を参照してください。

Zstdベースのストリームの場合#

安定性: 1 - Experimental

Zstdベースのストリームにはzlibオプションに相当するものがありますが、これらのオプションの範囲はzlibのものとは異なります。

  • zlibの level オプションは、Zstdの ZSTD_c_compressionLevel オプションに相当します。
  • zlibの windowBits オプションは、Zstdの ZSTD_c_windowLog オプションに相当します。

Zstd固有のオプションに関する詳細については、以下を参照してください。

フラッシュ#

圧縮ストリームで .flush() を呼び出すと、zlib は現在可能な限り多くの出力を返します。これは圧縮品質の低下を犠牲にする可能性がありますが、データをできるだけ早く利用可能にする必要がある場合に役立ちます。

次の例では、flush() を使用して、圧縮された部分的なHTTPレスポンスをクライアントに書き込みます。

import zlib from 'node:zlib';
import http from 'node:http';
import { pipeline } from 'node:stream';

http.createServer((request, response) => {
  // For the sake of simplicity, the Accept-Encoding checks are omitted.
  response.writeHead(200, { 'content-encoding': 'gzip' });
  const output = zlib.createGzip();
  let i;

  pipeline(output, response, (err) => {
    if (err) {
      // If an error occurs, there's not much we can do because
      // the server has already sent the 200 response code and
      // some amount of data has already been sent to the client.
      // The best we can do is terminate the response immediately
      // and log the error.
      clearInterval(i);
      response.end();
      console.error('An error occurred:', err);
    }
  });

  i = setInterval(() => {
    output.write(`The current time is ${Date()}\n`, () => {
      // The data has been passed to zlib, but the compression algorithm may
      // have decided to buffer the data for more efficient compression.
      // Calling .flush() will make the data available as soon as the client
      // is ready to receive it.
      output.flush();
    });
  }, 1000);
}).listen(1337);const zlib = require('node:zlib');
const http = require('node:http');
const { pipeline } = require('node:stream');

http.createServer((request, response) => {
  // For the sake of simplicity, the Accept-Encoding checks are omitted.
  response.writeHead(200, { 'content-encoding': 'gzip' });
  const output = zlib.createGzip();
  let i;

  pipeline(output, response, (err) => {
    if (err) {
      // If an error occurs, there's not much we can do because
      // the server has already sent the 200 response code and
      // some amount of data has already been sent to the client.
      // The best we can do is terminate the response immediately
      // and log the error.
      clearInterval(i);
      response.end();
      console.error('An error occurred:', err);
    }
  });

  i = setInterval(() => {
    output.write(`The current time is ${Date()}\n`, () => {
      // The data has been passed to zlib, but the compression algorithm may
      // have decided to buffer the data for more efficient compression.
      // Calling .flush() will make the data available as soon as the client
      // is ready to receive it.
      output.flush();
    });
  }, 1000);
}).listen(1337);

定数#

zlib 定数#

zlib.h で定義されているすべての定数は、require('node:zlib').constants でも定義されています。通常の操作では、これらの定数を使用する必要はありません。その存在が驚きとならないように文書化されています。このセクションは、zlib ドキュメントからほぼ直接引用されています。

以前は、定数は require('node:zlib') から直接利用可能でした (例: zlib.Z_NO_FLUSH)。モジュールから直接定数にアクセスすることは現在も可能ですが、非推奨です。

許可されるフラッシュ値。

  • zlib.constants.Z_NO_FLUSH
  • zlib.constants.Z_PARTIAL_FLUSH
  • zlib.constants.Z_SYNC_FLUSH
  • zlib.constants.Z_FULL_FLUSH
  • zlib.constants.Z_FINISH
  • zlib.constants.Z_BLOCK

圧縮/伸張関数のリターンコード。負の値はエラー、正の値は特別だが正常なイベントに使用されます。

  • zlib.constants.Z_OK
  • zlib.constants.Z_STREAM_END
  • zlib.constants.Z_NEED_DICT
  • zlib.constants.Z_ERRNO
  • zlib.constants.Z_STREAM_ERROR
  • zlib.constants.Z_DATA_ERROR
  • zlib.constants.Z_MEM_ERROR
  • zlib.constants.Z_BUF_ERROR
  • zlib.constants.Z_VERSION_ERROR

圧縮レベル。

  • zlib.constants.Z_NO_COMPRESSION
  • zlib.constants.Z_BEST_SPEED
  • zlib.constants.Z_BEST_COMPRESSION
  • zlib.constants.Z_DEFAULT_COMPRESSION

圧縮戦略。

  • zlib.constants.Z_FILTERED
  • zlib.constants.Z_HUFFMAN_ONLY
  • zlib.constants.Z_RLE
  • zlib.constants.Z_FIXED
  • zlib.constants.Z_DEFAULT_STRATEGY

Brotli 定数#

Brotliベースのストリームには、いくつかのオプションとその他の定数が利用可能です。

フラッシュ操作#

以下の値は、Brotliベースのストリームで有効なフラッシュ操作です。

  • zlib.constants.BROTLI_OPERATION_PROCESS (すべての操作のデフォルト)
  • zlib.constants.BROTLI_OPERATION_FLUSH (.flush() 呼び出し時のデフォルト)
  • zlib.constants.BROTLI_OPERATION_FINISH (最後のチャンクのデフォルト)
  • zlib.constants.BROTLI_OPERATION_EMIT_METADATA
    • この特定の操作は、Node.js のコンテキストでは使用が難しい場合があります。ストリーミング層により、どのデータがこのフレームで終わるかを知ることが困難なためです。また、現在 Node.js API を通じてこのデータを消費する方法はありません。
圧縮オプション#

Brotliエンコーダには、圧縮効率と速度に影響を与えるいくつかのオプションを設定できます。キーと値の両方は、zlib.constants オブジェクトのプロパティとしてアクセスできます。

最も重要なオプションは次のとおりです。

  • BROTLI_PARAM_MODE
    • BROTLI_MODE_GENERIC (デフォルト)
    • BROTLI_MODE_TEXT、UTF-8テキスト用に調整
    • BROTLI_MODE_FONT、WOFF 2.0フォント用に調整
  • BROTLI_PARAM_QUALITY
    • 範囲は BROTLI_MIN_QUALITY から BROTLI_MAX_QUALITY までで、デフォルトは BROTLI_DEFAULT_QUALITY です。
  • BROTLI_PARAM_SIZE_HINT
    • 予想される入力サイズを表す整数値。不明な入力サイズの場合はデフォルトで 0 になります。

以下のフラグは、圧縮アルゴリズムとメモリ使用量のチューニングを高度に制御するために設定できます。

  • BROTLI_PARAM_LGWIN
    • 範囲は BROTLI_MIN_WINDOW_BITS から BROTLI_MAX_WINDOW_BITS までで、デフォルトは BROTLI_DEFAULT_WINDOW です。BROTLI_PARAM_LARGE_WINDOW フラグが設定されている場合は、最大 BROTLI_LARGE_MAX_WINDOW_BITS までです。
  • BROTLI_PARAM_LGBLOCK
    • 範囲は BROTLI_MIN_INPUT_BLOCK_BITS から BROTLI_MAX_INPUT_BLOCK_BITS までです。
  • BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING
    • 伸張速度を優先して圧縮率を低下させるブールフラグ。
  • BROTLI_PARAM_LARGE_WINDOW
    • 「Large Window Brotli」モードを有効にするブールフラグ(RFC 7932 で標準化されたBrotli形式とは互換性がありません)。
  • BROTLI_PARAM_NPOSTFIX
    • 範囲は 0 から BROTLI_MAX_NPOSTFIX までです。
  • BROTLI_PARAM_NDIRECT
    • 範囲は 0 から 15 << NPOSTFIX までで、ステップは 1 << NPOSTFIX です。
伸張オプション#

伸張を制御するために、以下の高度なオプションが利用可能です。

  • BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION
    • 内部メモリ割り当てパターンに影響を与えるブールフラグ。
  • BROTLI_DECODER_PARAM_LARGE_WINDOW
    • 「Large Window Brotli」モードを有効にするブールフラグ(RFC 7932 で標準化されたBrotli形式とは互換性がありません)。

Zstd 定数#

安定性: 1 - Experimental

Zstdベースのストリームには、いくつかのオプションとその他の定数が利用可能です。

フラッシュ操作#

以下の値は、Zstdベースのストリームで有効なフラッシュ操作です。

  • zlib.constants.ZSTD_e_continue (すべての操作のデフォルト)
  • zlib.constants.ZSTD_e_flush (.flush() 呼び出し時のデフォルト)
  • zlib.constants.ZSTD_e_end (最後のチャンクのデフォルト)
圧縮オプション#

Zstdエンコーダには、圧縮効率と速度に影響を与えるいくつかのオプションを設定できます。キーと値の両方は、zlib.constants オブジェクトのプロパティとしてアクセスできます。

最も重要なオプションは次のとおりです。

  • ZSTD_c_compressionLevel
    • 事前に定義されたcLevelテーブルに従って圧縮パラメータを設定します。デフォルトレベルは ZSTD_CLEVEL_DEFAULT==3 です。
  • ZSTD_c_strategy
    • 圧縮戦略を選択します。
    • 可能な値は、以下の戦略オプションのセクションにリストされています。
戦略オプション#

以下の定数は、ZSTD_c_strategy パラメータの値として使用できます。

  • zlib.constants.ZSTD_fast
  • zlib.constants.ZSTD_dfast
  • zlib.constants.ZSTD_greedy
  • zlib.constants.ZSTD_lazy
  • zlib.constants.ZSTD_lazy2
  • zlib.constants.ZSTD_btlazy2
  • zlib.constants.ZSTD_btopt
  • zlib.constants.ZSTD_btultra
  • zlib.constants.ZSTD_btultra2

const stream = zlib.createZstdCompress({
  params: {
    [zlib.constants.ZSTD_c_strategy]: zlib.constants.ZSTD_btultra,
  },
}); 
宣言されたソースサイズ#

opts.pledgedSrcSize を介して、非圧縮入力の予想される合計サイズを指定することが可能です。入力の終わりにサイズが一致しない場合、圧縮はコード ZSTD_error_srcSize_wrong で失敗します。

伸張オプション#

伸張を制御するために、以下の高度なオプションが利用可能です。

  • ZSTD_d_windowLogMax
    • ホストを不合理なメモリ要件から保護するために、ストリーミングAPIがメモリバッファの割り当てを拒否するサイズ制限(2のべき乗)を選択します。

クラス: Options#

各zlibベースのクラスは options オブジェクトを取ります。オプションは必須ではありません。

一部のオプションは圧縮時にのみ関連し、伸張クラスでは無視されます。

詳細については、deflateInit2inflateInit2 のドキュメントを参照してください。

クラス: BrotliOptions#

各Brotliベースのクラスは options オブジェクトを取ります。すべてのオプションは任意です。

  • flush <integer> デフォルト: zlib.constants.BROTLI_OPERATION_PROCESS
  • finishFlush <integer> デフォルト: zlib.constants.BROTLI_OPERATION_FINISH
  • chunkSize <integer> デフォルト: 16 * 1024
  • params <Object> インデックス付けされた Brotliパラメータを含むキーと値のオブジェクト。
  • maxOutputLength <integer> 便利なメソッドを使用する際の出力サイズを制限します。デフォルト: buffer.kMaxLength
  • info <boolean> true の場合、bufferengine を持つオブジェクトを返します。デフォルト: false

例:

const stream = zlib.createBrotliCompress({
  chunkSize: 32 * 1024,
  params: {
    [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,
    [zlib.constants.BROTLI_PARAM_QUALITY]: 4,
    [zlib.constants.BROTLI_PARAM_SIZE_HINT]: fs.statSync(inputFile).size,
  },
}); 

クラス: zlib.BrotliCompress#

Brotliアルゴリズムを使用してデータを圧縮します。

クラス: zlib.BrotliDecompress#

Brotliアルゴリズムを使用してデータを伸張します。

クラス: zlib.Deflate#

deflate を使用してデータを圧縮します。

クラス: zlib.DeflateRaw#

deflate を使用してデータを圧縮し、zlib ヘッダを付加しません。

クラス: zlib.Gunzip#

gzipストリームを伸張します。

クラス: zlib.Gzip#

gzip を使用してデータを圧縮します。

クラス: zlib.Inflate#

deflateストリームを伸張します。

クラス: zlib.InflateRaw#

生のdeflateストリームを伸張します。

クラス: zlib.Unzip#

ヘッダを自動検出して、GzipまたはDeflateで圧縮されたストリームを伸張します。

クラス: zlib.ZlibBase#

node:zlib モジュールによってエクスポートされません。これは圧縮/伸張クラスの基底クラスであるため、ここに文書化されています。

このクラスは stream.Transform を継承しているため、node:zlib オブジェクトをパイプや同様のストリーム操作で使用できます。

zlib.bytesWritten#

zlib.bytesWritten プロパティは、バイトが処理される(派生クラスに応じて圧縮または伸張される)前にエンジンに書き込まれたバイト数を指定します。

zlib.close([callback])#

基になるハンドルを閉じます。

zlib.flush([kind, ]callback)#

  • kind デフォルト: zlibベースのストリームの場合は zlib.constants.Z_FULL_FLUSH、Brotliベースのストリームの場合は zlib.constants.BROTLI_OPERATION_FLUSH
  • callback <Function>

保留中のデータをフラッシュします。これを軽々しく呼び出さないでください。早すぎるフラッシュは圧縮アルゴリズムの有効性に悪影響を及ぼします。

これを呼び出すと、内部の zlib 状態からのデータのみがフラッシュされ、ストリームレベルでのフラッシュは一切行われません。むしろ、通常の .write() 呼び出しのように動作します。つまり、他の保留中の書き込みの後ろにキューイングされ、ストリームからデータが読み取られている場合にのみ出力を生成します。

zlib.params(level, strategy, callback)#

この関数はzlibベースのストリーム、つまりBrotliではないストリームでのみ利用可能です。

圧縮レベルと圧縮戦略を動的に更新します。deflateアルゴリズムにのみ適用されます。

zlib.reset()#

圧縮/伸張器を工場出荷時のデフォルトにリセットします。inflateおよびdeflateアルゴリズムにのみ適用されます。

クラス: ZstdOptions#

安定性: 1 - Experimental

各Zstdベースのクラスは options オブジェクトを取ります。すべてのオプションは任意です。

  • flush <integer> デフォルト: zlib.constants.ZSTD_e_continue
  • finishFlush <integer> デフォルト: zlib.constants.ZSTD_e_end
  • chunkSize <integer> デフォルト: 16 * 1024
  • params <Object> インデックス付けされた Zstdパラメータを含むキーと値のオブジェクト。
  • maxOutputLength <integer> 便利なメソッドを使用する際の出力サイズを制限します。デフォルト: buffer.kMaxLength
  • info <boolean> true の場合、bufferengine を持つオブジェクトを返します。デフォルト: false
  • dictionary <Buffer> 辞書と共通のパターンを共有するデータを圧縮または伸張する際に、圧縮効率を向上させるために使用されるオプションの辞書。

例:

const stream = zlib.createZstdCompress({
  chunkSize: 32 * 1024,
  params: {
    [zlib.constants.ZSTD_c_compressionLevel]: 10,
    [zlib.constants.ZSTD_c_checksumFlag]: 1,
  },
}); 

クラス: zlib.ZstdCompress#

安定性: 1 - Experimental

Zstdアルゴリズムを使用してデータを圧縮します。

クラス: zlib.ZstdDecompress#

安定性: 1 - Experimental

Zstdアルゴリズムを使用してデータを伸張します。

zlib.constants#

Zlib関連の定数を列挙したオブジェクトを提供します。

zlib.crc32(data[, value])#

  • data <string> | <Buffer> | <TypedArray> | <DataView> data が文字列の場合、計算に使用される前にUTF-8としてエンコードされます。
  • value <integer> オプションの開始値。32ビット符号なし整数でなければなりません。デフォルト: 0
  • 戻り値: <integer> チェックサムを含む32ビット符号なし整数。

data の32ビット巡回冗長検査チェックサムを計算します。value が指定されている場合、それがチェックサムの開始値として使用されます。それ以外の場合は、0が開始値として使用されます。

CRCアルゴリズムは、チェックサムを計算し、データ送信中のエラーを検出するために設計されています。暗号認証には適していません。

他のAPIとの一貫性を保つため、data が文字列の場合、計算に使用される前にUTF-8でエンコードされます。ユーザーがNode.jsのみを使用してチェックサムを計算し、照合する場合、これはデフォルトでUTF-8エンコーディングを使用する他のAPIとうまく機能します。

一部のサードパーティJavaScriptライブラリは、ブラウザで実行できるように、str.charCodeAt() に基づいて文字列のチェックサムを計算します。ユーザーがブラウザでこの種のライブラリで計算されたチェックサムと一致させたい場合、そのライブラリがNode.jsでも実行可能であれば、Node.jsで同じライブラリを使用する方が良いでしょう。ユーザーがそのようなサードパーティライブラリによって生成されたチェックサムと一致させるために zlib.crc32() を使用する必要がある場合:

  1. ライブラリが入力として Uint8Array を受け入れる場合、ブラウザで TextEncoder を使用して文字列をUTF-8エンコーディングの Uint8Array にエンコードし、ブラウザでUTF-8エンコードされた文字列に基づいてチェックサムを計算します。
  2. ライブラリが文字列のみを受け入れ、str.charCodeAt() に基づいてデータを計算する場合、Node.js側で、Buffer.from(str, 'utf16le') を使用して文字列をバッファに変換します。
import zlib from 'node:zlib';
import { Buffer } from 'node:buffer';

let crc = zlib.crc32('hello');  // 907060870
crc = zlib.crc32('world', crc);  // 4192936109

crc = zlib.crc32(Buffer.from('hello', 'utf16le'));  // 1427272415
crc = zlib.crc32(Buffer.from('world', 'utf16le'), crc);  // 4150509955const zlib = require('node:zlib');
const { Buffer } = require('node:buffer');

let crc = zlib.crc32('hello');  // 907060870
crc = zlib.crc32('world', crc);  // 4192936109

crc = zlib.crc32(Buffer.from('hello', 'utf16le'));  // 1427272415
crc = zlib.crc32(Buffer.from('world', 'utf16le'), crc);  // 4150509955

zlib.createBrotliCompress([options])#

新しい BrotliCompress オブジェクトを作成して返します。

zlib.createBrotliDecompress([options])#

新しい BrotliDecompress オブジェクトを作成して返します。

zlib.createDeflate([options])#

新しい Deflate オブジェクトを作成して返します。

zlib.createDeflateRaw([options])#

新しい DeflateRaw オブジェクトを作成して返します。

zlibを1.2.8から1.2.11にアップグレードした際、生のdeflateストリームで windowBits が8に設定されたときの動作が変更されました。zlibは、当初8に設定されていた場合、windowBits を自動的に9に設定していました。新しいバージョンのzlibは例外をスローするため、Node.jsは8の値を9にアップグレードするという元の動作を復元しました。これは、windowBits = 9 をzlibに渡すと、実際には8ビットウィンドウを効果的に使用する圧縮ストリームが生成されるためです。

zlib.createGunzip([options])#

新しい Gunzip オブジェクトを作成して返します。

zlib.createGzip([options])#

新しい Gzip オブジェクトを作成して返します。を参照してください。

zlib.createInflate([options])#

新しい Inflate オブジェクトを作成して返します。

zlib.createInflateRaw([options])#

新しい InflateRaw オブジェクトを作成して返します。

zlib.createUnzip([options])#

新しい Unzip オブジェクトを作成して返します。

zlib.createZstdCompress([options])#

安定性: 1 - Experimental

新しい ZstdCompress オブジェクトを作成して返します。

zlib.createZstdDecompress([options])#

安定性: 1 - Experimental

新しい ZstdDecompress オブジェクトを作成して返します。

便利なメソッド#

これらはすべて、最初の引数として <Buffer><TypedArray><DataView><ArrayBuffer>、または文字列を受け取り、オプションの2番目の引数で zlib クラスにオプションを提供し、指定されたコールバックを callback(error, result) で呼び出します。

すべてのメソッドには、同じ引数をコールバックなしで受け入れる *Sync 版があります。

zlib.brotliCompress(buffer[, options], callback)#

zlib.brotliCompressSync(buffer[, options])#

BrotliCompress を使用してデータのチャンクを圧縮します。

zlib.brotliDecompress(buffer[, options], callback)#

zlib.brotliDecompressSync(buffer[, options])#

BrotliDecompress を使用してデータのチャンクを伸張します。

zlib.deflate(buffer[, options], callback)#

zlib.deflateSync(buffer[, options])#

Deflate を使用してデータのチャンクを圧縮します。

zlib.deflateRaw(buffer[, options], callback)#

zlib.deflateRawSync(buffer[, options])#

DeflateRaw を使用してデータのチャンクを圧縮します。

zlib.gunzip(buffer[, options], callback)#

zlib.gunzipSync(buffer[, options])#

Gunzip を使用してデータのチャンクを伸張します。

zlib.gzip(buffer[, options], callback)#

zlib.gzipSync(buffer[, options])#

Gzip を使用してデータのチャンクを圧縮します。

zlib.inflate(buffer[, options], callback)#

zlib.inflateSync(buffer[, options])#

Inflate を使用してデータのチャンクを伸張します。

zlib.inflateRaw(buffer[, options], callback)#

zlib.inflateRawSync(buffer[, options])#

InflateRaw を使用してデータのチャンクを伸張します。

zlib.unzip(buffer[, options], callback)#

zlib.unzipSync(buffer[, options])#

Unzip を使用してデータのチャンクを伸張します。

zlib.zstdCompress(buffer[, options], callback)#

安定性: 1 - Experimental

zlib.zstdCompressSync(buffer[, options])#

安定性: 1 - Experimental

ZstdCompress を使用してデータのチャンクを圧縮します。

zlib.zstdDecompress(buffer[, options], callback)#

zlib.zstdDecompressSync(buffer[, options])#

安定性: 1 - Experimental

ZstdDecompress を使用してデータのチャンクを伸張します。