Zlib#

稳定性: 2 - 稳定

源代码: lib/zlib.js

node:zlib 模块提供了使用 Gzip、Deflate/Inflate、Brotli 和 Zstd 实现的压缩功能。

要访问它

import os 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 process from 'node:process';
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,除了那些显式同步的 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,再加上几个 KB 用于小对象。

例如,要将默认内存要求从 256K 降低到 128K,应将选项设置为

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

但是,这通常会降低压缩率。

inflate 的内存要求是(以字节为单位)1 << windowBits。 也就是说,windowBits = 15(默认值)为 32K,再加上几个 KB 用于小对象。

这是对大小为 chunkSize 的单个内部输出 slab 缓冲区(默认为 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 特定选项的更多详细信息,请参见下方

刷新#

在压缩流上调用 .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_TREES

压缩/解压缩函数的返回码。 负值表示错误,正值用于特殊但正常的事件。

  • 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
    • 布尔标志,启用“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
    • 布尔标志,启用“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。
声明的源大小#

可以通过 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 <函数>

刷新挂起的数据。 不要随意调用此函数,过早的刷新会对压缩算法的有效性产生负面影响。

调用此方法只会刷新内部 zlib 状态的数据,并且不会在流级别执行任何类型的刷新。 相反,它的行为类似于对 .write() 的正常调用,即它将在其他挂起的写入之后排队,并且仅在从流中读取数据时才会产生输出。

zlib.params(level, strategy, callback)#

此函数仅适用于基于 zlib 的流,即不适用于 Brotli。

动态更新压缩级别和压缩策略。 仅适用于 deflate 算法。

zlib.reset()#

将压缩器/解压缩器重置为出厂默认设置。 仅适用于 inflate 和 deflate 算法。

类: ZstdOptions#

稳定性: 1 - 实验性

每个基于 Zstd 的类都接受一个 options 对象。 所有选项都是可选的。

例如

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 <整数> 一个可选的起始值。 它必须是一个 32 位无符号整数。 默认值: 0
  • 返回: <整数> 包含校验和的 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 时的行为。 如果最初设置为 8,则 zlib 会自动将 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 - 实验性

创建并返回一个新的 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 解压一块数据。