Zlib#

穩定性:2 - 穩定

原始碼: lib/zlib.js

node:zlib 模組提供了使用 Gzip、Deflate/Inflate、Brotli 和 Zstd 實現的壓縮功能。

要訪問它

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

壓縮和解壓縮是圍繞 Node.js 流 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;
  });

執行緒池的使用和效能考量#

除了明確同步的 API 外,所有 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 定義的 gzipdeflatebrzstd 內容編碼機制的支援。

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 需要對 zlib 進行更少的呼叫,因為它能夠在每次 write 操作中處理更多的資料。因此,這是影響速度的另一個因素,但代價是記憶體使用量。

對於基於 Brotli 的流#

Brotli 流有與 zlib 選項等效的選項,儘管這些選項的範圍與 zlib 不同:

  • zlib 的 level 選項對應於 Brotli 的 BROTLI_PARAM_QUALITY 選項。
  • zlib 的 windowBits 選項對應於 Brotli 的 BROTLI_PARAM_LGWIN 選項。

有關 Brotli 特定選項的更多詳細資訊,請參見下文

對於基於 Zstd 的流#

穩定性:1 - 實驗性

Zstd 流有與 zlib 選項等效的選項,儘管這些選項的範圍與 zlib 不同:

  • zlib 的 level 選項對應於 Zstd 的 ZSTD_c_compressionLevel 選項。
  • zlib 的 windowBits 選項對應於 Zstd 的 ZSTD_c_windowLog 選項。

有關 Zstd 特定選項的更多詳細資訊,請參見下文

重新整理(Flushing)#

在壓縮流上呼叫 .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_QUALITYBROTLI_MAX_QUALITY,預設值為 BROTLI_DEFAULT_QUALITY
  • BROTLI_PARAM_SIZE_HINT
    • 表示預期輸入大小的整數值;對於未知輸入大小,預設為 0

以下標誌可用於對壓縮演算法和記憶體使用進行高階控制和調優:

  • BROTLI_PARAM_LGWIN
    • 範圍從 BROTLI_MIN_WINDOW_BITSBROTLI_MAX_WINDOW_BITS,預設值為 BROTLI_DEFAULT_WINDOW,如果設定了 BROTLI_PARAM_LARGE_WINDOW 標誌,則最高可達 BROTLI_LARGE_MAX_WINDOW_BITS
  • BROTLI_PARAM_LGBLOCK
    • 範圍從 BROTLI_MIN_INPUT_BLOCK_BITSBROTLI_MAX_INPUT_BLOCK_BITS
  • BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING
    • 一個布林標誌,透過犧牲壓縮率來提高解壓縮速度。
  • BROTLI_PARAM_LARGE_WINDOW
    • 一個布林標誌,啟用“大視窗 Brotli”模式(與 RFC 7932 中標準化的 Brotli 格式不相容)。
  • BROTLI_PARAM_NPOSTFIX
    • 範圍從 0BROTLI_MAX_NPOSTFIX
  • BROTLI_PARAM_NDIRECT
    • 範圍從 015 << NPOSTFIX,步長為 1 << NPOSTFIX
解壓縮器選項#

這些高階選項可用於控制解壓縮:

  • BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION
    • 一個布林標誌,影響內部記憶體分配模式。
  • BROTLI_DECODER_PARAM_LARGE_WINDOW
    • 一個布林標誌,啟用“大視窗 Brotli”模式(與 RFC 7932 中標準化的 Brotli 格式不相容)。

Zstd 常量#

穩定性:1 - 實驗性

對於基於 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,
  },
}); 
承諾的源大小(Pledged Source Size)#

可以透過 opts.pledgedSrcSize 指定未壓縮輸入的預期總大小。如果輸入結束時大小不匹配,壓縮將失敗,錯誤碼為 ZSTD_error_srcSize_wrong

解壓縮器選項#

這些高階選項可用於控制解壓縮:

  • ZSTD_d_windowLogMax
    • 選擇一個大小限制(以 2 的冪表示),超過該限制,流式 API 將拒絕分配記憶體緩衝區,以保護主機免受不合理的記憶體需求。

類:Options#

每個基於 zlib 的類都接受一個 options 物件。所有選項都不是必需的。

一些選項僅在壓縮時相關,並被解壓縮類忽略。

有關更多資訊,請參閱 deflateInit2inflateInit2 文件。

類:BrotliOptions#

每個基於 Brotli 的類都接受一個 options 物件。所有選項都是可選的。

例如:

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 - 實驗性

每個基於 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 - 實驗性

使用 Zstd 演算法壓縮資料。

類:zlib.ZstdDecompress#

穩定性:1 - 實驗性

使用 Zstd 演算法解壓縮資料。

zlib.constants#

提供一個列舉 Zlib 相關常量的物件。

zlib.crc32(data[, value])#

  • data <string> | <Buffer> | <TypedArray> | <DataView>data 是字串時,它將被編碼為 UTF-8 後用於計算。
  • value <integer> 一個可選的起始值。它必須是一個 32 位無符號整數。預設: 0
  • 返回:<integer> 一個包含校驗和的 32 位無符號整數。

計算 data 的 32 位迴圈冗餘校驗 (Cyclic Redundancy Check) 校驗和。如果指定了 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 過去會自動將 windowBits 設定為 9,如果它最初被設定為 8。新版本的 zlib 會丟擲異常,因此 Node.js 恢復了將值 8 升級到 9 的原始行為,因為向 zlib 傳遞 windowBits = 9 實際上會產生一個有效使用 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 - 實驗性

建立並返回一個新的 ZstdCompress 物件。

zlib.createZstdDecompress([options])#

穩定性:1 - 實驗性

建立並返回一個新的 ZstdDecompress 物件。

便捷方法#

所有這些方法都接受 <Buffer><TypedArray><DataView><ArrayBuffer> 或字串作為第一個引數,一個可選的第二個引數來為 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 - 實驗性

zlib.zstdCompressSync(buffer[, options])#

穩定性:1 - 實驗性

使用 ZstdCompress 壓縮資料塊。

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

zlib.zstdDecompressSync(buffer[, options])#

穩定性:1 - 實驗性

使用 ZstdDecompress 解壓縮資料塊。