Node.js v26.11.1 文档


Zlib#>

源代码: lib/zlib.js

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

🌐 The node:zlib module provides compression functionality implemented using Gzip, Deflate/Inflate, Brotli, and Zstd.

要访问它:

🌐 To access it:

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

压缩和解压缩是围绕 Node.js 流 API 构建的。

🌐 Compression and decompression are built around the Node.js Streams API.

通过将源流通过 zlib 的 Transform 流传入目标流,可以实现对流(例如文件)的压缩或解压缩:

🌐 Compressing or decompressing a stream (such as a file) can be accomplished by piping the source stream through a zlib Transform stream into a destination stream:

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 { 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:

🌐 Or, using the 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 { 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;
  });

也可以一步压缩或解压缩数据:

🌐 It is also possible to compress or decompress data in a single step:

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;
  });

线程池使用和性能注意事项#>

🌐 Threadpool usage and performance considerations

除了那些明确为同步的 API 之外,所有 zlib API 都使用 Node.js 内部线程池。这在某些应用中可能会导致意想不到的效果和性能限制。

🌐 All zlib APIs, except those that are explicitly synchronous, use the Node.js internal threadpool. This can lead to surprising effects and performance limitations in some applications.

同时创建和使用大量 zlib 对象可能导致显著的内存碎片化。

🌐 Creating and using a large number of zlib objects simultaneously can cause significant memory fragmentation.

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 实例。由于某些操作系统处理内存分配和释放的方式,这可能导致严重的内存碎片问题。

🌐 In the preceding example, 30,000 deflate instances are created concurrently. Because of how some operating systems handle memory allocation and deallocation, this may lead to significant memory fragmentation.

强烈建议将压缩操作的结果进行缓存,以避免重复工作。

🌐 It is strongly recommended that the results of compression operations be cached to avoid duplication of effort.

压缩 HTTP 请求和响应#>

🌐 Compressing HTTP requests and responses

node:zlib 模块可用于实现对 HTTP 定义的 gzip、deflate、br 和 zstd 内容编码机制的支持。

🌐 The node:zlib module can be used to implement support for the gzip, deflate, br, and zstd content-encoding mechanisms defined by HTTP.

HTTP Accept-Encoding 头用于 HTTP 请求中,以识别客户端接受的压缩编码。Content-Encoding 头用于识别实际应用于消息的压缩编码。

🌐 The HTTP Accept-Encoding header is used within an HTTP request to identify the compression encodings accepted by the client. The Content-Encoding header is used to identify the compression encodings actually applied to a message.

下面给出的示例被大幅简化,以展示基本概念。使用 zlib 编码可能成本较高,结果应当进行缓存。有关使用 zlib 时涉及的速度/内存/压缩权衡的更多信息,请参见 内存使用调整。

🌐 The examples given below are drastically simplified to show the basic concept. Using zlib encoding can be expensive, and the results ought to be cached. See Memory usage tuning for more information on the speed/memory/compression tradeoffs involved in zlib usage.

// 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,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;
  }
});// 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 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);// 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 方法在解压截断数据时会抛出错误。然而,如果已知数据不完整,或者只希望检查压缩文件的开头部分,则可以通过更改用于解压最后一块输入数据的刷新方法来抑制默认的错误处理:

🌐 By default, the zlib methods will throw an error when decompressing truncated data. However, if it is known that the data is incomplete, or the desire is to inspect only the beginning of a compressed file, it is possible to suppress the default error handling by changing the flushing method that is used to decompress the last chunk of input data:

// 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());
  }); 

这不会改变其他抛出错误的情况的行为,例如,当输入数据格式无效时。使用此方法,将无法判断输入是提前结束还是缺少完整性检查,因此需要手动检查解压后的结果是否有效。

🌐 This will not change the behavior in other error-throwing situations, e.g. when the input data has an invalid format. Using this method, it will not be possible to determine whether the input ended prematurely or lacks the integrity checks, making it necessary to manually check that the decompressed result is valid.

内存使用调整#>

🌐 Memory usage tuning

对于基于 zlib 的流#>

🌐 For zlib-based streams

来自 zlib/zconf.h,为 Node.js 使用而修改:

🌐 From zlib/zconf.h, modified for Node.js usage:

deflate 的内存要求是(以字节为单位):

🌐 The memory requirements for deflate are (in bytes):

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

也就是说:128K 用于 windowBits = 15 + 128K 用于 memLevel = 8(默认值),再加上几千字节用于小对象。

🌐 That is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects.

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

🌐 For example, to reduce the default memory requirements from 256K to 128K, the options should be set to:

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

然而,这通常会降低压缩性能。

🌐 This will, however, generally degrade compression.

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

🌐 The memory requirements for inflate are (in bytes) 1 << windowBits. That is, 32K for windowBits = 15 (default value) plus a few kilobytes for small objects.

这还包括一个大小为 chunkSize 的单一内部输出缓冲区,默认大小为16K。

🌐 This is in addition to a single internal output slab buffer of size chunkSize, which defaults to 16K.

zlib 压缩的速度最显著地受 level 设置影响。较高的压缩级别会带来更好的压缩效果,但完成的时间会更长。较低的压缩级别会导致压缩效果较差,但速度会快得多。

🌐 The speed of zlib compression is affected most dramatically by the level setting. A higher level will result in better compression, but will take longer to complete. A lower level will result in less compression, but will be much faster.

一般来说,较高的内存使用选项意味着 Node.js 调用 zlib 的次数会更少,因为它能够在每次 write 操作中处理更多的数据。因此,这是影响速度的另一个因素,但代价是增加了内存使用。

🌐 In general, greater memory usage options will mean that Node.js has to make fewer calls to zlib because it will be able to process more data on each write operation. So, this is another factor that affects the speed, at the cost of memory usage.

对于基于 Brotli 的流#>

🌐 For Brotli-based streams

对于基于 Brotli 的流,也存在与 zlib 选项相对应的选项,尽管这些选项的范围与 zlib 的不同:

🌐 There are equivalents to the zlib options for Brotli-based streams, although these options have different ranges than the zlib ones:

  • zlib 的 level 选项与 Brotli 的 BROTLI_PARAM_QUALITY 选项对应。
  • zlib 的 windowBits 选项与 Brotli 的 BROTLI_PARAM_LGWIN 选项相对应。

有关 Brotli 特定选项的更多详情,请参见 下面。

🌐 See below for more details on Brotli-specific options.

对于基于 Zstd 的流#>

🌐 For Zstd-based streams

稳定性: 1 - 实验性

对于基于 Zstd 的流,也存在与 zlib 选项相对应的选项,尽管这些选项的范围与 zlib 的不同:

🌐 There are equivalents to the zlib options for Zstd-based streams, although these options have different ranges than the zlib ones:

  • zlib 的 level 选项与 Zstd 的 ZSTD_c_compressionLevel 选项对应。
  • zlib 的 windowBits 选项对应 Zstd 的 ZSTD_c_windowLog 选项。

有关 Zstd 特定选项的更多详细信息,请参见 下面。

🌐 See below for more details on Zstd-specific options.

刷新#>

🌐 Flushing

在压缩流上调用 .flush() 会使 zlib 返回当前尽可能多的输出。这可能会以压缩质量下降为代价,但在需要尽快获取数据时非常有用。

🌐 Calling .flush() on a compression stream will make zlib return as much output as currently possible. This may come at the cost of degraded compression quality, but can be useful when data needs to be available as soon as possible.

在以下示例中,使用 flush() 将压缩的部分 HTTP 响应写入客户端:

🌐 In the following example, flush() is used to write a compressed partial HTTP response to the client:

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);

常量#>

🌐 Constants

zlib 常量#>

🌐 zlib constants

zlib.h 中定义的所有常量也都在 require('node:zlib').constants 中定义。在正常操作过程中,通常不需要使用这些常量。它们的文档是为了让它们的存在不令人惊讶。该部分几乎直接摘自 zlib 文档。

🌐 All of the constants defined in zlib.h are also defined on require('node:zlib').constants. In the normal course of operations, it will not be necessary to use these constants. They are documented so that their presence is not surprising. This section is taken almost directly from the zlib documentation.

以前,这些常量可以直接从 require('node:zlib') 获取,例如 zlib.Z_NO_FLUSH。目前仍然可以直接从模块访问这些常量,但这种做法已被弃用。

🌐 Previously, the constants were available directly from require('node:zlib'), for instance zlib.Z_NO_FLUSH. Accessing the constants directly from the module is currently still possible but is deprecated.

允许的刷新值。

🌐 Allowed flush values.

  • 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

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

🌐 Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events.

  • 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

压缩级别。

🌐 Compression levels.

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

压缩策略。

🌐 Compression strategy.

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

Brotli 常量#>

🌐 Brotli constants

对于基于 Brotli 的流,有几种选项和其他常量可用:

🌐 There are several options and other constants available for Brotli-based streams:

刷新操作#>

🌐 Flush operations

以下值是基于 Brotli 的流的有效刷新操作:

🌐 The following values are valid flush operations for Brotli-based streams:

  • 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 消费这些数据的方法。

压缩器选项#>

🌐 Compressor options

Brotli 编码器可以设置多个选项,这些选项会影响压缩效率和速度。键和值都可以作为 zlib.constants 对象的属性进行访问。

🌐 There are several options that can be set on Brotli encoders, affecting compression efficiency and speed. Both the keys and the values can be accessed as properties of the zlib.constants object.

最重要的选项是:

🌐 The most important options are:

  • 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。

可以设置以下标志,以便对压缩算法和内存使用进行高级控制:

🌐 The following flags can be set for advanced control over the compression algorithm and memory usage tuning:

  • 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。

解压选项#>

🌐 Decompressor options

这些高级选项可用于控制减压:

🌐 These advanced options are available for controlling decompression:

  • BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION
    • 影响内部内存分配模式的布尔标志。
  • BROTLI_DECODER_PARAM_LARGE_WINDOW
    • 布尔标志,用于启用“Large Window Brotli”模式(与RFC 7932标准化的Brotli格式不兼容)。

Zstd 常量#>

🌐 Zstd constants

稳定性: 1 - 实验性

对于基于 Zstd 的流,有几种选项和其他常量可用:

🌐 There are several options and other constants available for Zstd-based streams:

刷新操作#>

🌐 Flush operations

以下值是基于 Zstd 的流的有效刷新操作:

🌐 The following values are valid flush operations for Zstd-based streams:

  • zlib.constants.ZSTD_e_continue(所有操作的默认值)
  • zlib.constants.ZSTD_e_flush(调用 .flush() 时的默认值)
  • zlib.constants.ZSTD_e_end(最后一个数据块的默认值)

压缩器选项#>

🌐 Compressor options

Zstd 编码器可以设置多个选项,这些选项会影响压缩效率和速度。键和值都可以作为 zlib.constants 对象的属性来访问。

🌐 There are several options that can be set on Zstd encoders, affecting compression efficiency and speed. Both the keys and the values can be accessed as properties of the zlib.constants object.

最重要的选项是:

🌐 The most important options are:

  • ZSTD_c_compressionLevel
    • 根据预定义的 cLevel 表设置压缩参数。默认级别是 ZSTD_CLEVEL_DEFAULT==3。
  • ZSTD_c_strategy
    • 选择压缩策略。
    • 可能的取值列在下面的策略选项部分。

策略选项#>

🌐 Strategy options

以下常量可以用作 ZSTD_c_strategy 参数的值:

🌐 The following constants can be used as values for the ZSTD_c_strategy parameter:

  • 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

示例:

🌐 Example:

const stream = zlib.createZstdCompress({
  params: {
    [zlib.constants.ZSTD_c_strategy]: zlib.constants.ZSTD_btultra,
  },
}); 

保证源大小#>

🌐 Pledged Source Size

可以通过 opts.pledgedSrcSize 指定未压缩输入的预计总大小,该值必须是非负的安全整数。如果输入结束时大小不匹配,压缩将失败,并返回代码 ZSTD_error_srcSize_wrong。

🌐 It's possible to specify the expected total size of the uncompressed input via opts.pledgedSrcSize, which must be a non-negative safe integer. If the size doesn't match at the end of the input, compression will fail with the code ZSTD_error_srcSize_wrong.

zlib.zstdCompress() 默认将 opts.pledgedSrcSize 设置为其输入的字节长度。

解压选项#>

🌐 Decompressor options

这些高级选项可用于控制减压:

🌐 These advanced options are available for controlling decompression:

  • ZSTD_d_windowLogMax
    • 选择一个大小限制(以 2 的幂为单位),超过该限制时,流式 API 将拒绝分配内存缓冲区,以保护主机免受不合理的内存需求影响。

类:Options#>

🌐 Class: Options

每个基于 zlib 的类都接受一个 options 对象。无需提供选项。

🌐 Each zlib-based class takes an options object. No options are required.

有些选项仅在压缩时相关,解压类会忽略这些选项。

🌐 Some options are only relevant when compressing and are ignored by the decompression classes.

  • flush <integer> 默认: zlib.constants.Z_NO_FLUSH
  • finishFlush <integer> 默认: zlib.constants.Z_FINISH
  • chunkSize <integer> 默认: 16 * 1024
  • windowBits <integer>
  • level <integer> (仅限压缩)
  • memLevel <integer> (仅限压缩)
  • strategy <integer> (仅限压缩)
  • dictionary <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> (仅限压缩/解压缩,默认使用空字典)
  • info <boolean> (如果 true,则返回包含 buffer 和 engine 的对象。)
  • maxOutputLength <integer> 在使用 便捷方法 时限制输出大小。默认值: buffer.kMaxLength
  • rejectGarbageAfterEnd <boolean> 如果 true,当在压缩流结束后检测到多余输入时,解压会失败。这包括无法读取的字节,以及在解压 gzip 时,第一个成员之后的额外 gzip 成员。默认值: false

查看更多信息,请参阅 deflateInit2 和 inflateInit2 文档。

🌐 See the deflateInit2 and inflateInit2 documentation for more information.

类:BrotliOptions#>

🌐 Class: BrotliOptions

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

🌐 Each Brotli-based class takes an options object. All options are optional.

  • 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,则返回包含 buffer 和 engine 的对象。默认值: false
  • rejectGarbageAfterEnd <boolean> 如果 true,当第一个完整压缩流后输入仍然存在时解压失败。默认值: false

例如:

🌐 For example:

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#>

🌐 Class: zlib.BrotliCompress

使用 Brotli 算法压缩数据。

🌐 Compress data using the Brotli algorithm.

类:zlib.BrotliDecompress#>

🌐 Class: zlib.BrotliDecompress

使用 Brotli 算法解压缩数据。

🌐 Decompress data using the Brotli algorithm.

类:zlib.Deflate#>

🌐 Class: zlib.Deflate

使用 deflate 压缩数据。

🌐 Compress data using deflate.

类:zlib.DeflateRaw#>

🌐 Class: zlib.DeflateRaw

使用 deflate 压缩数据,并且不要附加 zlib 头。

🌐 Compress data using deflate, and do not append a zlib header.

类:zlib.Gunzip#>

🌐 Class: zlib.Gunzip

解压缩 gzip 流。

🌐 Decompress a gzip stream.

类:zlib.Gzip#>

🌐 Class: zlib.Gzip

使用 gzip 压缩数据。

🌐 Compress data using gzip.

类:zlib.Inflate#>

🌐 Class: zlib.Inflate

解压缩 deflate 流。

🌐 Decompress a deflate stream.

类:zlib.InflateRaw#>

🌐 Class: zlib.InflateRaw

解压缩原始的 deflate 流。

🌐 Decompress a raw deflate stream.

类:zlib.Unzip#>

🌐 Class: zlib.Unzip

通过自动检测头部来解压 Gzip 或 Deflate 压缩的流。

🌐 Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header.

类:zlib.ZipBuffer#>

🌐 Class: zlib.ZipBuffer

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个类)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this class among them) emits an experimental warning the first time; merely importing node:zlib does not.

在内存中对已经存在于 Buffer、TypedArray、DataView 或 ArrayBuffer 的 ZIP 档案条目提供 零拷贝 的视图。它的条目集合可以编辑——可以添加或删除条目——但是,与 ZipFile 不同,这些修改 不会 写入源缓冲区:新添加的条目会作为独立的内存 ZipEntry 保存(传入的缓冲区是固定大小视图,无法追加内容),而删除操作只是从 ZipBuffer 的索引中移除条目。原始字节从未被修改。zipBuffer.toBuffer() 会将当前的条目集合序列化成一个新的档案。

🌐 An in-memory, zero-copy view over the entries of a ZIP archive already held in a Buffer, TypedArray, DataView, or ArrayBuffer. Its set of entries can be edited - entries added or removed - but, unlike ZipFile, those edits are not written into the source buffer: a newly added entry is held as a separate in-memory ZipEntry (the passed buffer is a fixed-size view with no room to append to), and removal just drops the entry from ZipBuffer's index. The original bytes are never modified. zipBuffer.toBuffer() serializes the current set of entries into a fresh archive.

ZipBuffer 不会复制你提供的归档文件。它只是保持对那块内存的一个视图,并且懒惰地、直接地读取每个条目的内容,这就是无论归档大小多大,构建都很便宜的原因。代价是,在 ZipBuffer 或从中获得的任何 ZipEntry 仍在使用时,你绝不能修改或重用那块内存——包括作为 TypedArray/DataView 支撑的 ArrayBuffer。如果源可能会被修改或重用,请传递一个副本(例如 Buffer.from(source))。

add() 和 toBuffer() 各自都有一个 *Sync 对应的版本(addSync(), toBufferSync()),它们会同步执行相同的压缩工作。就像同步的 node:fs API 一样,这些会阻塞 Node.js 的事件循环以及后续的 JavaScript 执行,直到操作完成;只在需要同步执行的情况下使用它们(例如短期运行的脚本或启动代码),不要在必须保持响应的代码中使用。

import { ZipBuffer } from 'node:zlib';
import { readFileSync, writeFileSync } from 'node:fs';
import { Buffer } from 'node:buffer';

const zip = new ZipBuffer(readFileSync('archive.zip'));
for (const [name, entry] of zip) {
  console.log(name, entry.size);
}
await zip.add('hello.txt', Buffer.from('Hello, world!'));
zip.delete('unwanted.txt');
writeFileSync('archive.zip', await zip.toBuffer());const { ZipBuffer } = require('node:zlib');
const { readFileSync, writeFileSync } = require('node:fs');

async function main() {
  const zip = new ZipBuffer(readFileSync('archive.zip'));
  for (const [name, entry] of zip) {
    console.log(name, entry.size);
  }
  await zip.add('hello.txt', Buffer.from('Hello, world!'));
  zip.delete('unwanted.txt');
  writeFileSync('archive.zip', await zip.toBuffer());
}
main();

new zlib.ZipBuffer(buffer)#>

解析归档的中央目录。如果 buffer 不是格式良好且受支持的归档,会抛出 ERR_ZIP_INVALID_ARCHIVE 或 ERR_ZIP_UNSUPPORTED_FEATURE 错误。

🌐 Parses the archive's central directory. Throws an ERR_ZIP_INVALID_ARCHIVE or ERR_ZIP_UNSUPPORTED_FEATURE error if buffer is not a well-formed, supported archive.

buffer 没有被复制:ZipBuffer 保留了它的零拷贝视图(对于底层的 ArrayBuffer 的 TypedArray、DataView 或 ArrayBuffer),并按需直接从中读取条目内容。在 ZipBuffer 或从中读取的任何条目仍然存在的情况下,不要修改或重用那块内存;如果可能会改变,就传一个副本。

zipBuffer.add(filename, data[, options])#>

相当于 zipBuffer.addEntry(await zlib.ZipEntry.create(filename, data, options))。

🌐 Equivalent to zipBuffer.addEntry(await zlib.ZipEntry.create(filename, data, options)).

zipBuffer.addSync(filename, data[, options])#>

zipBuffer.add() 的同步版本。等同于 zipBuffer.addEntry(zlib.ZipEntry.createSync(filename, data, options))。

🌐 The synchronous version of zipBuffer.add(). Equivalent to zipBuffer.addEntry(zlib.ZipEntry.createSync(filename, data, options)).

zipBuffer.addEntry(entry)#>

  • entry ZipEntry
  • 返回:ZipEntry entry.

添加一个已构建的条目,以其自身的 zipEntry.name 作为键。会替换任何同名的现有条目。

🌐 Adds an already-built entry, keyed by its own zipEntry.name. Replaces any existing entry of that name.

zipBuffer.clear()#>

删除所有条目。

🌐 Removes every entry.

zipBuffer.comment#>

归档级别的注释,会在 zipBuffer.toBuffer() 调用中逐字节保留,除非被覆盖。当字节是有效的 UTF-8 时会被解码为 UTF-8,否则会解码为 CP437(该字段本身没有编码标志)。

🌐 The archive-level comment, preserved byte-for-byte across zipBuffer.toBuffer() calls unless overridden. The bytes are decoded as UTF-8 when they are valid UTF-8 and as CP437 otherwise (the field carries no encoding flag of its own).

zipBuffer.delete(name)#>

  • name <string>
  • 返回:<boolean> true 如果存在名为 name 的条目并已被移除。

zipBuffer.entries()#>

zipBuffer.forEach(callback[, thisArg])#>

按档案列出的顺序,对每个条目调用一次 callback。

🌐 Calls callback once for each entry, in the order the archive lists them.

zipBuffer.get(name)#>

如果归档中没有名为 name 的条目,则抛出 ERR_ZIP_ENTRY_NOT_FOUND。

🌐 Throws ERR_ZIP_ENTRY_NOT_FOUND if the archive has no entry named name.

zipBuffer.has(name)#>

zipBuffer.keys()#>

zipBuffer.size#>

档案里的条目数量。

🌐 The number of entries in the archive.

zipBuffer.toBuffer([options])#>

  • options <string> | <Object> 归档评论,作为 { comment: options } 的简写。
    • comment <string> 一个归档评论。默认:zipBuffer.comment。
    • baseOffset <number> 将存档记录的每个偏移量移动这么多字节,所以即使序列化的存档被写在最终文件的起始位置以外,它也是自描述的——例如,在同一输出中已经写入了 baseOffset 字节的其他内容之后。默认值: 0。
  • 返回:<Promise> 充满了一个包含序列化档案的<Buffer>。

将当前条目集按添加或读取的顺序序列化到一个新的归档中,并在需要时自动切换到 Zip64 结构(参见 zlib.createZipArchive())。

🌐 Serializes the current set of entries - in the order they were added or read - into a fresh archive, switching to Zip64 structures automatically as needed (see zlib.createZipArchive()).

zipBuffer.toBufferSync([options])#>

zipBuffer.toBuffer() 的同步版本(见 zlib.createZipArchiveSync())。

🌐 The synchronous version of zipBuffer.toBuffer() (see zlib.createZipArchiveSync()).

zipBuffer.values()#>

zipBuffer.writable#>

总是 true。

🌐 Always true.

类:zlib.ZipEntry#>

🌐 Class: zlib.ZipEntry

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个类)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this class among them) emits an experimental warning the first time; merely importing node:zlib does not.

ZIP 压缩包里的单个文件或目录。实例由 ZipBuffer 和 ZipFile 生成,或者直接使用 ZipEntry.create()/ZipEntry.createStream() 创建用于写入。

🌐 A single file or directory inside a ZIP archive. Instances are produced by ZipBuffer and ZipFile, or created directly for writing with ZipEntry.create()/ZipEntry.createStream().

create() 和 content() 各自都有一个 *Sync 对应(流式的 contentIterator() 没有)。和同步的 node:fs API 一样,这些会阻塞 Node.js 事件循环和后续的 JavaScript 执行,直到操作完成(包括任何压缩/解压过程);只有在适合同步执行的情况下使用它们(例如短脚本或启动代码),不要在必须保持响应的代码中使用。

静态方法:zlib.ZipEntry.create(filename, data[, options])#>

🌐 Static method: zlib.ZipEntry.create(filename, data[, options])

  • filename <string> 档案中的条目名称。结尾的 / 表示这是一个目录条目。
  • data <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> 条目的完整、未压缩内容。当 filename 指向一个目录时,必须为空。
  • options <Object>
    • comment <string> 一条留言。
    • mode <integer> Unix权限位。默认值: 0o644(目录为 0o755)。
    • modified <Date> 条目的修改时间。**默认:**当前时间。
    • method <string> 'deflate'、'store' 或 'zstd' 之一。默认: 'deflate',但目录和空内容始终会被存储。
  • 返回:<Promise> 充满了ZipEntry。

压缩 data(除非 method 是 'store',或者压缩不会减小它的大小)并计算它的 CRC-32。

🌐 Compresses data (unless method is 'store', or compression would not reduce its size) and computes its CRC-32.

当条目最终以未压缩的形式存储时(因为 method 是 'store',或者压缩不会减小大小),条目会保留 data 的零拷贝视图,而不是复制,而且它的 CRC-32 已经被记录。创建条目后不要修改 data;如果可能会改变的话,请传一个副本。

🌐 When the entry ends up stored uncompressed (because method is 'store', or because compression would not reduce the size), the entry retains a zero-copy view of data rather than a copy, and its CRC-32 has already been recorded. Do not mutate data after creating the entry; pass a copy if it might change.

ZIP 用在 modified 的 MS-DOS 日期/时间字段的分辨率是 2 秒,而且没有时区。当 modified 不在完整的 2 秒边界上时,还会写入一个 Info-ZIP 扩展时间戳额外字段,记录完整的(UTC)秒,以便时间能更准确地回传(见 zipEntry.modified)。这适用于每一个条目的创建路径。

🌐 The MS-DOS date/time fields ZIP uses for modified have 2-second resolution and no time zone. When modified does not fall on a whole 2-second boundary, an Info-ZIP extended-timestamp extra field is written as well, recording the whole (UTC) second so the time round-trips more precisely (see zipEntry.modified). This applies to every entry-creation path.

静态方法:zlib.ZipEntry.createStream(filename, source[, options])#>

🌐 Static method: zlib.ZipEntry.createStream(filename, source[, options])

  • filename <string> 存档中条目的名称。不能以 / 结尾。
  • source <AsyncIterable> 将条目的未压缩内容作为 Uint8Array 块输出。
  • options <Object>
    • comment <string> 一条留言。
    • mode <integer> Unix 权限位。默认值: 0o644。
    • modified <Date> 条目的修改时间。**默认:**当前时间。
    • method <string> 'deflate'、'store' 或 'zstd' 中的一个。默认: 'deflate'。
  • 返回:ZipEntry

创建一个条目,其内容在由 zlib.createZipArchive() 序列化时会实时压缩,而不会在内存中缓存 source。它的 size、compressedSize 和 crc32 只有在序列化完成后才可用。没有同步对应项:流式条目只有在异步、逐步生成的 source 场景下才有意义。

🌐 Creates an entry whose content is compressed on the fly as it is serialized by zlib.createZipArchive(), without buffering source in memory. Its size, compressedSize, and crc32 only become available once serialization has finished. There is no synchronous counterpart: streaming entries only make sense with an asynchronous, incrementally-produced source.

source 只会在序列化时被耗尽一次。在那之前,这个条目没有可读内容,所以 zipEntry.content()、zipEntry.contentSync() 和 zipEntry.contentIterator() 会抛出 ERR_INVALID_STATE。如果通过将它添加到可写的 ZipFile 并使用 zipFile.addEntry()(或 addEntrySync())来序列化它,那么它会就地提升为一个指向刚写入副本的文件支持条目,因此只要 ZipFile 保持打开,它就可以被读取(并且可以再次序列化)。用任何其他方式序列化(例如直接通过 zlib.createZipArchive())会让它耗尽且不可读。

因为 source 可能持有操作系统资源(比如一个文件读取流),所以流式条目是可释放的:它的 Symbol.dispose 和 Symbol.asyncDispose 方法会销毁 source,如果它还没有被使用的话。传递给归档的条目会由该归档释放(见 zlib.createZipArchive());只有在条目创建后从未交给归档时,才直接释放它。对于非流式条目,释放操作是无效的——特别是基于文件的条目从不会关闭它借用的 ZipFile 描述符。

🌐 Because source may hold an operating-system resource (a file read stream, say), a streaming entry is disposable: its Symbol.dispose and Symbol.asyncDispose methods destroy source if it has not been consumed. An entry passed to an archive is disposed by that archive (see zlib.createZipArchive()); dispose an entry directly only when it was built but never handed to one. Disposal is a no-op for non-streaming entries - in particular a file-backed entry never closes the ZipFile descriptor it borrows.

静态方法:zlib.ZipEntry.createSymlink(filename, target[, options])#>

🌐 Static method: zlib.ZipEntry.createSymlink(filename, target[, options])

  • filename <string> 档案里的条目名称。
  • target <string> 符号链接的目标路径
  • options <Object>
    • comment <string> 一条留言。
    • mode <integer> Unix 权限位。默认值: 0o777。
    • modified <Date> 条目的修改时间。默认: 当前时间。
  • 返回:ZipEntry

创建一个符号链接条目:一个存储的条目,其内容为 target,并且其 Unix 模式类型位将其标记为符号链接,因此当它被读取回时,zipEntry.isSymlink 为 true。支持符号链接条目的提取工具会重建该链接;将 target 视为不可信(参考 zipEntry.name 关于路径安全)。

🌐 Creates a symbolic-link entry: a stored entry whose content is target and whose Unix mode type bits mark it as a symlink, so zipEntry.isSymlink is true when it is read back. Extraction tools that honor symlink entries recreate the link; treat target as untrusted (see zipEntry.name on path safety).

静态方法:zlib.ZipEntry.createSync(filename, data[, options])#>

🌐 Static method: zlib.ZipEntry.createSync(filename, data[, options])

zlib.ZipEntry.create() 的同步版本。

🌐 The synchronous version of zlib.ZipEntry.create().

静态方法:zlib.ZipEntry.read(buffer)#>

🌐 Static method: zlib.ZipEntry.read(buffer)

直接解析 buffer 中的每一条记录,而不将其索引到 ZipBuffer。像 ZipBuffer 一样,生成的条目持有对 buffer 的零拷贝视图,而不是其内容的副本,所以同样的规则适用:在任何条目仍在使用时,不要修改或重用 buffer。

🌐 Parses every entry out of buffer directly, without indexing it into a ZipBuffer. Like ZipBuffer, the yielded entries hold zero-copy views of buffer rather than copies of their content, so the same rule applies: do not mutate or reuse buffer while any of them is still in use.

zipEntry.comment#>

zipEntry.compressed#>

true 如果条目的内容以压缩形式存储(任何压缩方法,目前是 deflate 或 Zstandard);false 如果以未压缩形式存储。

zipEntry.compressedSize#>

zipEntry.content([options])#>

  • options <Object>
  • 返回:<Promise> 充满了一个 <Buffer>,其中包含条目的解压内容。这个缓冲区是一个全新的副本,不与档案或条目创建时的数据共享任何内存。

如果条目声明的大小超过 maxSize,会抛出 ERR_ZIP_ENTRY_TOO_LARGE 错误;如果内容未通过 CRC-32 校验或与声明的大小不符,会抛出 ERR_ZIP_ENTRY_CORRUPT 错误;对于内容尚不可用的流式条目 (zlib.ZipEntry.createStream()),会抛出 ERR_INVALID_STATE 错误(参见该方法了解流式条目何时可读)。

🌐 Throws an ERR_ZIP_ENTRY_TOO_LARGE error if the entry's declared size exceeds maxSize, an ERR_ZIP_ENTRY_CORRUPT error if the content fails CRC-32 verification or does not match its declared size, and an ERR_INVALID_STATE error for a streaming entry (zlib.ZipEntry.createStream()) whose content is not yet available (see that method for when a streaming entry becomes readable).

zipEntry.contentSync([options])#>

zipEntry.content() 的同步版本。

🌐 The synchronous version of zipEntry.content().

zipEntry.contentIterator([options])#>

  • options <Object>
    • verify <boolean> 验证条目的 CRC-32 校验和。默认值:true。
    • maxSize <number> 在解压任何内容之前,拒绝声明超过这么多未压缩字节的内容。**默认:**无限制。
  • 返回:<AsyncIterator> <Buffer> 个条目解压内容的块。

与 zipEntry.content() 不同,这不会将整个成员缓存在内存中。对于一个基于文件的条目(由 zipFile.get() 返回的条目),压缩字节会在迭代器被使用时从磁盘读取,而且不会保留任何内容;条目只有在其 ZipFile 打开时才有效。

🌐 Unlike zipEntry.content(), this does not buffer the whole member in memory. For a file-backed entry (one returned by zipFile.get()) the compressed bytes are read from disk as the iterator is consumed and nothing is retained; the entry is valid only while its ZipFile is open.

因为流式处理是用于任意大成员的有界内存路径,所以它不会像zipEntry.content()那样被zlib.getMaxZipContentSize()限制——那种默认设置是为了保护单次大分配,而流式处理永远不会进行这种分配。输出仍然按每个块的声明未压缩大小有限制;可以传入maxSize来施加明确的上限。

🌐 Because streaming is the bounded-memory path for arbitrarily large members, it is not capped by zlib.getMaxZipContentSize() the way zipEntry.content() is - that default guards a single large allocation, which streaming never makes. Output is still bounded per chunk to the declared uncompressed size; pass maxSize to impose an explicit ceiling.

对于没有压缩存储的内存条目,生成的块是该条目保留内容的零拷贝视图(见 zipEntry.rawContent);不要修改它们。

🌐 For an in-memory entry stored without compression, the yielded chunks are zero-copy views of the entry's retained content (see zipEntry.rawContent); do not mutate them.

生成的块在迭代器完成之前都是临时的。CRC-32 校验(以及最终声明大小的检查)只能在所有字节读取完之后才能进行,因此一个损坏或截断的条目会通过迭代器在最后一个块之后抛出异常来报告,而不是在第一个块之前。每个块仍然是有边界的,所以总量从不会超过声明的大小或 maxSize,但是如果消费者不应该对未验证的字节进行操作,就应该先缓存这些字节(或者使用 zipEntry.content(),它会在返回任何数据之前进行验证),而不是边收边处理块。

🌐 The yielded chunks are provisional until the iterator completes. CRC-32 verification (and the final declared-size check) can only run once every byte has been read, so a corrupt or truncated entry is reported by the iterator throwing after the last chunk, not before the first. Each chunk is still bounded so the total never exceeds the declared size or maxSize, but a consumer that must not act on unverified bytes should buffer them (or use zipEntry.content(), which verifies before returning anything) rather than processing chunks as they arrive.

zipEntry.crc32#>

zipEntry.flags#>

条目的原始通用位标志。

🌐 The entry's raw general-purpose bit flag.

zipEntry.isDirectory#>

true 如果该条目是一个目录(其名称以 / 结尾)。

zipEntry.isFile#>

true 如果该条目是常规文件——也就是说,它既不是目录,也不是符号链接。

zipEntry.isSymlink#>

true 如果条目是符号链接(其 Unix 模式类型位为 S_IFLNK);其内容为链接目标。对于非类 Unix 系统生成的归档始终为 false。在解压时,将符号链接的目标视为不可信——关于路径安全,请参见 zipEntry.name。

zipEntry.mode#>

条目的 Unix 模式权限位,包括 setuid、setgid 和 sticky 位(低 12 位,0o7777),如果归档不是在类 Unix 系统上创建的则为 0。这里不包括文件类型位;请使用 zipEntry.isDirectory / zipEntry.isSymlink 来表示类型。

🌐 The entry's Unix mode permission bits, including the setuid, setgid, and sticky bits (the low 12 bits, 0o7777), or 0 if the archive was not written on a Unix-like system. The file-type bits are not included here; use zipEntry.isDirectory / zipEntry.isSymlink for the type.

zipEntry.modified#>

条目的最后修改时间。如果压缩包在额外字段中有更高精度的时间戳——比如 NTFS(0x000a)、Info-ZIP 扩展(0x5455)或 Info-ZIP Unix(0x5855)字段,就像大多数现代工具写的那样——会使用那个绝对的(UTC)时间;否则就用粗略的本地时间 MS-DOS 日期/时间字段(2 秒分辨率)。

🌐 The entry's last-modification time. When the archive carries a higher-fidelity timestamp in an extra field — an NTFS (0x000a), Info-ZIP extended (0x5455), or Info-ZIP Unix (0x5855) field, as most modern tools write — that absolute (UTC) time is used; otherwise the coarse, local-time MS-DOS date/time field (2-second resolution) is used.

有些工具只在本地文件头里存储它们的高精度时间戳,所以对于基于文件的条目(比如 zipFile.get() 返回的那种),第一次读取这个属性时可能会进行一次小的同步定位磁盘读取来获取那个文件头。如果读取失败,值会默默地退回到中央目录的数据。

🌐 Some tools store their high-fidelity timestamp only in the local file header, so on a file-backed entry (one returned by zipFile.get()) the first read of this property may perform a small synchronous positioned disk read to resolve that header. If that read fails, the value silently falls back to the central-directory data.

zipEntry.method#>

条目的原始压缩方法:0 表示存储,8 表示压缩,93 表示 Zstandard。

🌐 The entry's raw compression method: 0 for stored, 8 for deflate, 93 for Zstandard.

zipEntry.name#>

条目的名称是从中央目录解码的,它被视为权威 — 当本地文件头不一致时会被忽略,所以一个头信息不匹配(“ZIP混乱”)的压缩文件不会让 name 与读取到的内容不一致。当存在有效的 Info-ZIP Unicode 路径附加字段 (0x7075) 时,会从中解码字节;否则,如果语言编码标志(通用位 11)被设置 或字节是有效的 UTF-8(很多工具写 UTF-8 名称时从未设置过该标志),就按 UTF-8 解码;如果都不是,则按 CP437 — 历史默认 — 解码。原始字节请参见 zipEntry.nameBuffer。

🌐 The entry's name, decoded from the central directory, which is treated as authoritative — a local file header that disagrees is ignored, so a mismatched-header ("ZIP-confusion") archive cannot make name disagree with what is read. The bytes are decoded from a valid Info-ZIP Unicode Path extra field (0x7075) when one is present; otherwise as UTF-8 when the language-encoding flag (general-purpose bit 11) is set or the bytes are valid UTF-8 (plenty of tools wrote UTF-8 names without ever setting the flag); and as CP437 — the historical default — only when they are not. See zipEntry.nameBuffer for the raw bytes.

名称会被逐字返回:它从不进行规范化,包含 ..、开头的 /、驱动器字母或反斜杠的名称既不会被重写,也不会被拒绝。ZipFile/ZipBuffer 从不写入磁盘,因此在解压时防范路径遍历(“Zip Slip”)是调用方的责任。

🌐 The name is returned verbatim: it is never normalized, and a name containing .., a leading /, a drive letter, or backslashes is neither rewritten nor rejected. A ZipFile/ZipBuffer never writes to disk, so guarding against path traversal ("Zip Slip") when extracting is the caller's responsibility.

zipEntry.nameBuffer#>

条目的原始名称字节,在进行任何字符解码之前。当归档的名称使用 UTF-8 或 CP437 以外的编码,而且调用者想自己解码时,这很有用。

🌐 The entry's raw name bytes, before any character decoding. Useful when the archive's names are in an encoding other than UTF-8 or CP437 and the caller wants to decode them itself.

zipEntry.rawContent#>

条目的原始内容(如果适用,还压缩着)在内存中保存时的样子,或者当没有可暴露的内存缓冲区时为 null —— 对于用 zlib.ZipEntry.createStream() 创建的条目,或者由 zipFile.get() 返回的基于文件的条目,其字节按需从磁盘读取而不是保留在内存中。要读取基于文件的条目,请使用 zipEntry.content() 或 zipEntry.contentIterator()。

🌐 The entry's raw (still compressed, if applicable) content when it is held in memory, or null when there is no in-memory buffer to expose - for an entry created with zlib.ZipEntry.createStream(), or a file-backed entry returned by zipFile.get(), whose bytes are read from disk on demand rather than retained. Use zipEntry.content() or zipEntry.contentIterator() to read a file-backed entry.

zipEntry.size#>

条目的未压缩大小,以字节为单位。

🌐 The entry's uncompressed size, in bytes.

类:zlib.ZipFile#>

🌐 Class: zlib.ZipFile

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个类)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this class among them) emits an experimental warning the first time; merely importing node:zlib does not.

对磁盘上 ZIP 压缩包条目的随机访问视图。只会预先读取压缩包的尾部和中央目录;成员内容则按需从磁盘懒加载。当使用 { writable: true } 打开时可写:zipFile.addEntry()/zipFile.add() 会在中央目录原来的位置追加新成员的数据,然后紧接着重写中央目录;zipFile.delete() 则只重写中央目录。两者都意味着方法返回的 Promise 一旦完成,文件就被修改了。被删除或替换的成员会留下空闲空间;zipFile.compact() 会生成一个没有这些空闲空间的流。

🌐 A random-access view over the entries of a ZIP archive on disk. Only the archive's tail and central directory are read up front; member content is read from disk lazily, on demand. Writable when opened with { writable: true }: zipFile.addEntry()/zipFile.add() append the new member's data where the central directory used to be, then rewrite the central directory immediately after it; zipFile.delete() just rewrites the central directory. Both mean the file is altered as soon as the method's returned Promise fulfills. Deleted or replaced members are left behind as dead space; zipFile.compact() produces a stream with none.

这些就地编辑 不是崩溃原子性的。中央目录是就地重写的,所以如果写入过程中失败——比如磁盘满了、设备断开、进程被杀掉——可能会导致磁盘上的归档文件只写了一半或者中央目录丢失,也就是说无法读取,尽管之前的成员数据是完整的。被拒绝的调用会显示底层错误,而且 ZipFile 对象仍然可用(它的内存视图不会被丢弃,所以调用者可以尝试恢复——比如用 zipFile.compact() 在其他地方重新写入条目),但这个内存视图可能已经和磁盘上的字节不匹配。如果需要在失败情况下保持数据可靠性,应该写入副本,或者用 compact() 写入一个新文件。

🌐 These in-place edits are not crash-atomic. Rewriting the central directory happens in place, so a write that fails partway - the disk fills, the device disconnects, the process is killed - can leave the archive on disk with a partial or missing central directory, i.e. unreadable, even though the member data before it is intact. The rejected call surfaces the underlying error and the ZipFile object is left usable (its in-memory view is not discarded, so a caller can attempt recovery - for example re-writing the entries elsewhere with zipFile.compact()), but that in-memory view may no longer match the bytes on disk. Write to a copy, or compact() into a fresh file, when durability across a failure matters.

每个方法都有一个 *Sync 对应的版本。和同步的 node:fs API 一样,这些方法会阻塞 Node.js 的事件循环和后续的 JavaScript 执行,直到操作完成;只在需要同步执行的情况下使用它们(例如短生命周期脚本或启动代码),不要在必须保持响应的代码中使用。如果在同一个 ZipFile 上的异步 add()、addEntry()、delete() 或 close() 还没有完成时调用同步方法,它会抛出 ERR_INVALID_STATE,因为让两者交错执行可能会破坏存档。

🌐 Every method has a *Sync counterpart. As with the synchronous node:fs APIs, these block the Node.js event loop and further JavaScript execution until the operation completes; use them only where synchronous execution is appropriate (for example, short-lived scripts or startup code), not in code that must stay responsive. A synchronous method throws ERR_INVALID_STATE if called while an asynchronous add(), addEntry(), delete(), or close() on the same ZipFile has not settled yet, since letting the two interleave could corrupt the archive.

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

const zip = await ZipFile.open('archive.zip', { writable: true });
try {
  const entry = await zip.get('member.txt');
  console.log((await entry.content()).toString());
  for await (const chunk of await zip.stream('huge.bin')) {
    // Process each chunk without buffering the whole member.
  }
  await zip.add('new.txt', Buffer.from('hello'));
  await zip.delete('unwanted.txt');
} finally {
  await zip.close();
}const { ZipFile } = require('node:zlib');

async function main() {
  const zip = await ZipFile.open('archive.zip', { writable: true });
  try {
    const entry = await zip.get('member.txt');
    console.log((await entry.content()).toString());
    for await (const chunk of await zip.stream('huge.bin')) {
      // Process each chunk without buffering the whole member.
    }
    await zip.add('new.txt', Buffer.from('hello'));
    await zip.delete('unwanted.txt');
  } finally {
    await zip.close();
  }
}
main();

静态方法:zlib.ZipFile.open(filename[, options])#>

🌐 Static method: zlib.ZipFile.open(filename[, options])

如果存档的中央目录太大,无法缓存在内存中,就会抛出 ERR_ZIP_ARCHIVE_TOO_LARGE 错误。

🌐 Throws an ERR_ZIP_ARCHIVE_TOO_LARGE error if the archive's central directory is too large to buffer in memory.

静态方法:zlib.ZipFile.openSync(filename[, options])#>

🌐 Static method: zlib.ZipFile.openSync(filename[, options])

zlib.ZipFile.open() 的同步版本。

🌐 The synchronous version of zlib.ZipFile.open().

zipFile.add(filename, data[, options])#>

相当于 zipFile.addEntry(await zlib.ZipEntry.create(filename, data, options))。

🌐 Equivalent to zipFile.addEntry(await zlib.ZipEntry.create(filename, data, options)).

zipFile.addEntry(entry)#>

  • entry ZipEntry
  • 返回:<Promise> 充满了 entry。

在当前中央目录开始的位置写入 entry,然后重写中央目录以包含它,替换任何同名的现有条目。如果 ZipFile 不是以 { writable: true } 打开的,则抛出 ERR_ZIP_NOT_WRITABLE。

🌐 Writes entry where the central directory currently starts, then rewrites the central directory to include it, replacing any existing entry of the same name. Throws ERR_ZIP_NOT_WRITABLE if the ZipFile was not opened with { writable: true }.

返回的(相同的)entry 保持可读:用 zlib.ZipEntry.createStream() 创建的流式条目,本来序列化一次就会被消耗,现在就地升级为指向刚写入副本的文件支持条目(在这个 ZipFile 打开时有效)。内存中的条目保持自己的缓冲区不变。

🌐 The returned (same) entry is left readable: a streaming entry created with zlib.ZipEntry.createStream(), which would otherwise be spent once serialized, is promoted in place to a file-backed entry pointing at the copy just written (valid while this ZipFile is open). In-memory entries keep their own buffer unchanged.

zipFile.addEntrySync(entry)#>

  • entry ZipEntry
  • 返回:ZipEntry entry.

zipFile.addEntry() 的同步版本。entry 不能是一个待处理的流式条目(使用 zlib.ZipEntry.createStream() 创建的那种)——没有同步的方法来清空它的异步源。

🌐 The synchronous version of zipFile.addEntry(). entry must not be a pending streaming entry (one created with zlib.ZipEntry.createStream()) - there is no synchronous way to drain its asynchronous source.

zipFile.addSync(filename, data[, options])#>

zipFile.add() 的同步版本。等同于 zipFile.addEntrySync(zlib.ZipEntry.createSync(filename, data, options))。

🌐 The synchronous version of zipFile.add(). Equivalent to zipFile.addEntrySync(zlib.ZipEntry.createSync(filename, data, options)).

zipFile.close()#>

关闭底层的文件句柄。

🌐 Closes the underlying file handle.

关闭不会使未完成的对象失效:之前由 zipFile.get() 返回的 ZipEntry 对象以及 ZipFile 自身的方法返回的对象,如果在关闭后使用,将会出现系统级错误(例如 EBADF),而不是专门的 Node.js 错误代码。zipFile.closeSync() 也同样适用。

🌐 Closing does not invalidate outstanding objects: ZipEntry objects previously returned by zipFile.get() and the ZipFile's own methods will fail with system-level errors (for example EBADF) if used after close, rather than a dedicated Node.js error code. The same applies to zipFile.closeSync().

zipFile.closeSync()#>

zipFile.close() 的同步版本。

🌐 The synchronous version of zipFile.close().

zipFile.comment#>

归档级别的注释,在 zipFile.addEntry()/zipFile.delete() 调用中逐字节保留。当字节是有效的 UTF-8 时会被解码为 UTF-8,否则会解码为 CP437(该字段本身不带任何编码标志)。

🌐 The archive-level comment, preserved byte-for-byte across zipFile.addEntry()/zipFile.delete() calls. The bytes are decoded as UTF-8 when they are valid UTF-8 and as CP437 otherwise (the field carries no encoding flag of its own).

zipFile.compact([comment])#>

不会修改打开的文件;将结果传输到一个新文件中:

🌐 Does not modify the open file; pipe the result into a new one:

import { createWriteStream } from 'node:fs';
zip.compact().pipe(createWriteStream('compacted.zip')); 

zipFile.compactSync([comment])#>

zipFile.compact() 的同步版本不会修改已打开的文件。

🌐 The synchronous version of zipFile.compact(). Does not modify the open file.

zipFile.delete(name)#>

  • name <string>
  • 返回:<Promise> 如果存在名为 name 的条目并被移除,则返回 true,否则返回 false。

重写中央目录而不写入任何新内容——归档不会增长。如果 ZipFile 没有用 { writable: true } 打开,会抛出 ERR_ZIP_NOT_WRITABLE。

🌐 Rewrites the central directory without writing any new content - the archive does not grow. Throws ERR_ZIP_NOT_WRITABLE if the ZipFile was not opened with { writable: true }.

zipFile.deleteSync(name)#>

  • name <string>
  • 返回:<boolean> 如果存在名为 name 的条目并已被移除,则返回 true,否则返回 false。

zipFile.delete() 的同步版本。

🌐 The synchronous version of zipFile.delete().

zipFile.entries()#>

zipFile.entriesSync()#>

  • 返回:<Iterator> [name, entry] 对,其中 entry 是已解析的 ZipEntry(不是 Promise)。

zipFile.entries() 的同步版本。

🌐 The synchronous version of zipFile.entries().

zipFile.forEach(callback[, thisArg])#>

zipFile.forEachSync(callback[, thisArg])#>

zipFile.forEach() 的同步版本:callback 是在一个已解析的 ZipEntry 而不是 Promise 上被调用的。

🌐 The synchronous version of zipFile.forEach(): callback is invoked with a resolved ZipEntry instead of a Promise.

zipFile.get(name)#>

返回一个懒加载的、文件支持的 ZipEntry,用于 name。这里不会从磁盘读取任何内容,也不会缓冲内容:返回的条目在每次访问时直接从文件中读取(对于 zipEntry.content(),还会解压其成员),而 ZipFile 不会保留任何成员内容。只有在这个 ZipFile 打开时,条目才有效。稍后读取其内容可能会抛出 ERR_ZIP_ENTRY_TOO_LARGE,如果成员太大而无法放入单一缓冲区;可以改用 zipEntry.contentIterator()(或 zipFile.stream())。如果归档中没有名为 name 的条目,会抛出 ERR_ZIP_ENTRY_NOT_FOUND。

🌐 Returns a lazy, file-backed ZipEntry for name. Nothing is read from disk here and no content is buffered: the returned entry reads (and, for zipEntry.content(), decompresses) its member straight from the file on each access, and the ZipFile retains no member content. The entry is valid only while this ZipFile is open. Reading its content later may throw ERR_ZIP_ENTRY_TOO_LARGE if the member is too large to hold in a single buffer; use zipEntry.contentIterator() (or zipFile.stream()) instead. Throws ERR_ZIP_ENTRY_NOT_FOUND if the archive has no entry named name.

zipFile.getSync(name)#>

zipFile.get() 的同步版本。像 get() 一样,它一开始不会读取任何内容,只会构建延迟句柄,所以它本身不会因为 I/O 而阻塞 —— 但通过返回的条目(比如 zipEntry.contentSync())后续进行的读取会阻塞;参见上文关于同步方法的说明。

🌐 The synchronous version of zipFile.get(). Like get(), it reads nothing up front and only builds the lazy handle, so it does not itself block on I/O - but reads performed later through the returned entry (such as zipEntry.contentSync()) do; see the note above on synchronous methods.

zipFile.has(name)#>

zipFile.keys()#>

zipFile.size#>

档案里的条目数量。

🌐 The number of entries in the archive.

zipFile.stream(name[, options])#>

  • name <string>
  • options <Object>
    • verify <boolean> 验证条目的 CRC-32 校验和。默认值:true。
    • maxSize <number> 拒绝声明超过此数量未压缩字节的内容。**默认值:**无限制。
  • 返回:<Promise> 充满了成员的解压内容的 <stream.Readable>,无需将整个成员缓存在内存中。

方便的封装器,会解析为 Readable 在 zipFile.get()(name) 的 zipEntry.contentIterator() 上;压缩的字节会在读取流时从磁盘中获取。如果档案中没有名为 name 的条目,返回的 promise 会被 ERR_ZIP_ENTRY_NOT_FOUND 拒绝。

🌐 Convenience wrapper that resolves to a Readable over zipEntry.contentIterator() of zipFile.get()(name); the compressed bytes are read from disk as the stream is consumed. The returned promise rejects with ERR_ZIP_ENTRY_NOT_FOUND if the archive has no entry named name.

zipFile.values()#>

zipFile.valuesSync()#>

zipFile.values() 的同步版本。

🌐 The synchronous version of zipFile.values().

zipFile.writable#>

这个 ZipFile 是否是用 { writable: true } 打开的。

🌐 Whether this ZipFile was opened with { writable: true }.

类:zlib.ZlibBase#>

🌐 Class: zlib.ZlibBase

不是由 node:zlib 模块导出的。之所以在这里有文档说明,是因为它是压缩器/解压器类的基类。

🌐 Not exported by the node:zlib module. It is documented here because it is the base class of the compressor/decompressor classes.

这个类继承自 stream.Transform,允许 node:zlib 对象在管道和类似的流操作中使用。

🌐 This class inherits from stream.Transform, allowing node:zlib objects to be used in pipes and similar stream operations.

zlib.bytesWritten#>

zlib.bytesWritten 属性指定写入引擎的字节数,在这些字节被处理(压缩或解压缩,根据派生类的不同而适用)之前。

🌐 The zlib.bytesWritten property specifies the number of bytes written to the engine, before the bytes are processed (compressed or decompressed, as appropriate for the derived class).

zlib.close([callback])#>

关闭底层句柄。

🌐 Close the underlying handle.

zlib.flush([kind, ]callback)#>

  • kind 默认: zlib 流为 zlib.constants.Z_FULL_FLUSH,Brotli 流为 zlib.constants.BROTLI_OPERATION_FLUSH,Zstd 流为 zlib.constants.ZSTD_e_flush。
  • callback <Function>

刷新挂起的数据。不要轻率调用此操作,过早刷新会对压缩算法的效果产生负面影响。

🌐 Flush pending data. Don't call this frivolously, premature flushes negatively impact the effectiveness of the compression algorithm.

调用这个方法只会将数据从内部的 zlib 状态中刷新出来,并不会在流级别上执行任何类型的刷新。它的行为更像是正常的 .write() 调用,即它会排在其他待处理写操作的队列中,只有在从流中读取数据时才会产生输出。

🌐 Calling this only flushes data from the internal zlib state, and does not perform flushing of any kind on the streams level. Rather, it behaves like a normal call to .write(), i.e. it will be queued up behind other pending writes and will only produce output when data is being read from the stream.

zlib.params(level, strategy, callback)#>

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

🌐 This function is only available for zlib-based streams, i.e. not Brotli.

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

🌐 Dynamically update the compression level and compression strategy. Only applicable to deflate algorithm.

zlib.reset()#>

对于压缩和解压流,将压缩器/解压器重置为出厂默认设置。

🌐 For inflate and deflate streams, reset the compressor/decompressor to factory defaults.

对于 Brotli 流,可以在保留已配置的参数和字典的情况下,开始新的压缩或解压缩会话。

🌐 For Brotli streams, start a new compression or decompression session while preserving the configured parameters and dictionary.

对于 Zstd 流,取消当前帧并开始一个新会话,同时保留已配置的参数和字典。如果 pledgedSrcSize 已配置用于 Zstd 压缩器,它将在下一帧中再次适用。

🌐 For Zstd streams, cancel the current frame and start a new session while preserving the configured parameters and dictionary. If pledgedSrcSize was configured for a Zstd compressor, it applies again to the next frame.

在 gzip 流输出了不完整成员后重置流,会导致流报 ERR_ZLIB_INCOMPLETE_FRAME 错误。在此时重置会丢弃成员状态,而已写出的字节仍保留在输出流的开头,导致无法解码。应该调用 .end(),或者重新开始一个新的 gzip 流。封装在 zlib 中的 deflate 在刷新后仍可能 reset();重用压缩器的调用者会丢弃第一次的输出。原始 deflate 没有封装头,所以刷新后 reset() 仍会进行拼接。

🌐 Resetting a gzip stream after it has emitted output for an incomplete member causes the stream to error with ERR_ZLIB_INCOMPLETE_FRAME. Resetting at that point would discard the member state while the bytes already written out remain at the start of the output stream, leaving it undecodable. Call .end(), or start over with a new gzip stream, instead. zlib-wrapped deflate may still reset() after a flush; callers that reuse the compressor discard the first output. Raw deflate has no wrapper header, so reset() after a flush still concatenates.

在写入进行时调用 reset() 会抛出 Error。

🌐 Calling reset() while a write is in progress throws an Error.

在 Zstd 压缩帧未完成但已生成输出后重置它,会导致流出现 ERR_ZLIB_INCOMPLETE_FRAME 错误。在那时候重置会丢弃帧状态,而已写出的字节仍然在输出流的开头,导致无法解码。你应该调用 .end(),或者从一个新的流重新开始。

🌐 Resetting an incomplete Zstd compression frame after it has emitted output causes the stream to error with ERR_ZLIB_INCOMPLETE_FRAME. Resetting at that point would discard the frame state while the bytes already written out remain at the start of the output stream, leaving it undecodable. Call .end(), or start over with a new stream, instead.

类:ZstdOptions#>

🌐 Class: ZstdOptions

稳定性: 1 - 实验性

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

🌐 Each Zstd-based class takes an options object. All options are optional.

  • flush <integer> 默认: zlib.constants.ZSTD_e_continue
  • finishFlush <integer> 默认: zlib.constants.ZSTD_e_end
  • chunkSize <integer> 默认: 16 * 1024
  • params <Object> 包含索引 Zstd 参数 的键值对象。
  • pledgedSrcSize <number> 未压缩输入的预期总大小。它必须是非负的安全整数,并且在压缩完成时必须与输入大小匹配。仅适用于 Zstd 压缩器。
  • maxOutputLength <integer> 在使用 便捷方法 时限制输出大小。默认值: buffer.kMaxLength
  • info <boolean> 如果 true,则返回包含 buffer 和 engine 的对象。默认值: false
  • dictionary <Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> 可选字典,用于在压缩或解压与字典共享常见模式的数据时提高压缩效率。
  • rejectGarbageAfterEnd <boolean> 如果 true,在完整的 Zstd 帧序列之后输入仍然存在时,解压会失败。默认值: false

例如:

🌐 For example:

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

类:zlib.ZstdCompress#>

🌐 Class: zlib.ZstdCompress

稳定性: 1 - 实验性

使用 Zstd 算法压缩数据。

🌐 Compress data using the Zstd algorithm.

类:zlib.ZstdDecompress#>

🌐 Class: zlib.ZstdDecompress

稳定性: 1 - 实验性

使用 Zstd 算法解压数据。连接的 Zstd 和可跳过的帧会被解码为一个单独的流。

🌐 Decompress data using the Zstd algorithm. Concatenated Zstd and skippable frames are decoded as a single stream.

zlib.constants#>

提供枚举 Zlib 相关常量的对象。

🌐 Provides an object enumerating Zlib-related constants.

zlib.crc32(data[, value])#>

  • data <string> | <Buffer> | <TypedArray> | <DataView> 当 data 是字符串时,它将在用于计算之前被编码为 UTF-8。
  • value <integer> 一个可选的起始值。它必须是一个 32 位无符号整数。默认值: 0
  • 返回:<integer> 一个包含校验和的32位无符号整数。

计算 data 的 32 位 循环冗余校验 校验和。如果指定了 value,则将其用作校验和的起始值,否则使用 0 作为起始值。

🌐 Computes a 32-bit Cyclic Redundancy Check checksum of data. If value is specified, it is used as the starting value of the checksum, otherwise, 0 is used as the starting value.

CRC 算法旨在计算校验和并检测数据传输中的错误。它不适用于密码学身份验证。

🌐 The CRC algorithm is designed to compute checksums and to detect error in data transmission. It's not suitable for cryptographic authentication.

为了与其他 API 保持一致,如果 data 是字符串,它将在用于计算之前以 UTF-8 编码。如果用户仅使用 Node.js 来计算和匹配校验和,这与默认使用 UTF-8 编码的其他 API 可以很好地配合。

🌐 To be consistent with other APIs, if the data is a string, it will be encoded with UTF-8 before being used for computation. If users only use Node.js to compute and match the checksums, this works well with other APIs that uses the UTF-8 encoding by default.

一些第三方 JavaScript 库会基于 str.charCodeAt() 对字符串计算校验和,以便在浏览器中运行。 如果用户希望匹配在浏览器中由此类库计算的校验和,最好在 Node.js 中使用相同的库(如果它也可以在 Node.js 中运行)。 如果用户必须使用 zlib.crc32() 来匹配由此类第三方库生成的校验和:

🌐 Some third-party JavaScript libraries compute the checksum on a string based on str.charCodeAt() so that it can be run in browsers. If users want to match the checksum computed with this kind of library in the browser, it's better to use the same library in Node.js if it also runs in Node.js. If users have to use zlib.crc32() to match the checksum produced by such a third-party library:

  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 对象。

🌐 Creates and returns a new BrotliCompress object.

zlib.createBrotliDecompress([options])#>

创建并返回一个新的 BrotliDecompress 对象。

🌐 Creates and returns a new BrotliDecompress object.

zlib.createDeflate([options])#>

创建并返回一个新的 Deflate 对象。

🌐 Creates and returns a new Deflate object.

zlib.createDeflateRaw([options])#>

创建并返回一个新的 DeflateRaw 对象。

🌐 Creates and returns a new DeflateRaw object.

将 zlib 从 1.2.8 升级到 1.2.11 后,当 windowBits 为原始 deflate 流设置为 8 时,其行为发生了变化。zlib 会在最初设置为 8 时自动将 windowBits 设置为 9。较新的 zlib 版本会抛出异常,因此 Node.js 恢复了将 8 的值升级为 9 的原始行为,因为将 windowBits = 9 传递给 zlib 实际上会生成一个有效只使用 8 位窗口的压缩流。

🌐 An upgrade of zlib from 1.2.8 to 1.2.11 changed behavior when windowBits is set to 8 for raw deflate streams. zlib would automatically set windowBits to 9 if was initially set to 8. Newer versions of zlib will throw an exception, so Node.js restored the original behavior of upgrading a value of 8 to 9, since passing windowBits = 9 to zlib actually results in a compressed stream that effectively uses an 8-bit window only.

zlib.createGunzip([options])#>

创建并返回一个新的 Gunzip 对象。

🌐 Creates and returns a new Gunzip object.

zlib.createGzip([options])#>

创建并返回一个新的 Gzip 对象。请参阅 例子。

🌐 Creates and returns a new Gzip object. See example.

zlib.createInflate([options])#>

创建并返回一个新的 Inflate 对象。

🌐 Creates and returns a new Inflate object.

zlib.createInflateRaw([options])#>

创建并返回一个新的 InflateRaw 对象。

🌐 Creates and returns a new InflateRaw object.

zlib.createUnzip([options])#>

创建并返回一个新的 Unzip 对象。

🌐 Creates and returns a new Unzip object.

zlib.createZipArchive(entries[, options])#>

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个函数)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this function among them) emits an experimental warning the first time; merely importing node:zlib does not.

  • entries <Iterable> | <AsyncIterable> 的ZipEntry.
  • options <string> | <Object> 归档评论,作为 { comment: options } 的简写。
    • comment <string> 一条存档评论。
    • baseOffset <number> 每个本地/中央头都会将归档记录偏移这么多字节,所以即使在它之前写入了其他内容,输出的流也是自描述的——例如,可以在已经向同一文件写入 baseOffset 字节之后再追加归档,而不是从文件开头开始。默认: 0。
  • 返回:<stream.Readable> 序列化归档的字节流。

将 entries 序列化到 ZIP 压缩包中,一旦条目数量或任何偏移量或大小超过经典 32/16 位 ZIP 字段能容纳的范围,就会自动切换到 Zip64 结构。返回的 Readable 也是同样 <Buffer> 块的 AsyncIterable 流式对象。

🌐 Serializes entries into a ZIP archive, switching to Zip64 structures automatically once the entry count, or any offset or size, exceeds what the classic 32-/16-bit ZIP fields can hold. The returned Readable is also an AsyncIterable of the same <Buffer> chunks it streams.

条目是按迭代顺序写入的,而且不会对名称进行去重:如果一个可迭代对象生成两个同名条目,归档中会包含它们两个,而且大多数解压工具会保留后出现的那个。ZipBuffer 和 ZipFile 的 add() 方法则是按名称替换条目。

🌐 Entries are written in iteration order and nothing deduplicates names: an iterable that yields two entries with the same name produces an archive containing both, and most extraction tools keep the one that appears later. ZipBuffer and ZipFile add() methods replace entries by name instead.

返回的流拥有这些条目:每个条目在归档生成时会被使用,之后不能重复使用。这对于流式条目(来自 zlib.ZipEntry.createStream())尤其重要,因为它们持有底层资源,比如文件读取流。如果在完全消费之前销毁返回的流——例如 pipeline() 的目标失败——它会处理掉正在序列化的条目以及所有排队的条目,销毁它们的资源以防泄漏。要么将流消费到末尾,要么销毁它(直接销毁,通过失败的 pipeline(),或用 await using 销毁),以确保清理;一个既没有被消费也没有被销毁的流无法释放任何资源。一个从未交给归档的 ZipEntry 可以直接用 Symbol.dispose / Symbol.asyncDispose 释放。

🌐 The entries are owned by the returned stream: each is consumed as the archive is produced and must not be reused afterwards. This matters for streaming entries (from zlib.ZipEntry.createStream()), which hold an underlying source such as a file read stream. If the returned stream is destroyed before it is fully consumed - for example, the destination of a pipeline() fails - it disposes the entry it was serializing and every entry still queued behind it, destroying their sources so no descriptor leaks. Consume the stream to the end, or destroy it (directly, through a failed pipeline(), or with await using), to guarantee this cleanup; a stream that is neither consumed nor destroyed cannot release anything. A ZipEntry that is never handed to an archive can be released directly with Symbol.dispose / Symbol.asyncDispose.

如果归档注释经过 UTF-8 编码后超过 65,535 字节,会抛出 ERR_ZIP_ARCHIVE_TOO_LARGE 错误。

🌐 Throws an ERR_ZIP_ARCHIVE_TOO_LARGE error if the archive comment exceeds 65,535 bytes when encoded as UTF-8.

import { createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { Buffer } from 'node:buffer';
import { ZipEntry, createZipArchive } from 'node:zlib';

const entries = [
  await ZipEntry.create('hello.txt', Buffer.from('Hello, world!')),
  await ZipEntry.create('data/', Buffer.alloc(0)),
];
await pipeline(
  createZipArchive(entries, 'created by node:zlib'),
  createWriteStream('archive.zip'),
);const { createWriteStream } = require('node:fs');
const { pipeline } = require('node:stream/promises');
const { ZipEntry, createZipArchive } = require('node:zlib');

async function main() {
  const entries = [
    await ZipEntry.create('hello.txt', Buffer.from('Hello, world!')),
    await ZipEntry.create('data/', Buffer.alloc(0)),
  ];
  await pipeline(
    createZipArchive(entries, 'created by node:zlib'),
    createWriteStream('archive.zip'),
  );
}
main();

传递 options.baseOffset 会生成一个归档文件,当它放在同一文件的其他内容之后时立即有效,而不依赖于读取器的自解压归档检测来补偿偏移:

🌐 Passing options.baseOffset produces an archive that is valid immediately when placed after other content in the same file, without relying on a reader's self-extracting-archive detection to compensate for the shift:

import { createWriteStream } from 'node:fs';
import { Buffer } from 'node:buffer';
import { ZipEntry, createZipArchive } from 'node:zlib';

const prefix = Buffer.from('#!/bin/sh\nexit 0\n');
const entries = [await ZipEntry.create('hello.txt', Buffer.from('Hello, world!'))];
const out = createWriteStream('self-extracting.zip');
out.write(prefix);
createZipArchive(entries, { baseOffset: prefix.byteLength }).pipe(out); 

zlib.createZipArchiveSync(entries[, options])#>

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个函数)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this function among them) emits an experimental warning the first time; merely importing node:zlib does not.

zlib.createZipArchive() 的同步版本会阻塞 Node.js 事件循环以及后续的 JavaScript 执行,直到整个归档(包括任何 deflate 处理)完成;只在同步执行合适的情况下使用(例如短期脚本或启动代码),不要在必须保持响应的代码中使用。entries 必须是一个普通(同步的)Iterable——使用 zlib.ZipEntry.createStream() 创建的流式条目在轮到序列化时会报错,因为耗尽其异步源没有同步的对应方法。

🌐 The synchronous version of zlib.createZipArchive(). Blocks the Node.js event loop and further JavaScript execution until the whole archive (including any deflate passes) has been produced; use only where synchronous execution is appropriate (for example, short-lived scripts or startup code), not in code that must stay responsive. entries must be a plain (synchronous) Iterable - a streaming entry created with zlib.ZipEntry.createStream() throws when its turn to serialize comes up, since draining its asynchronous source has no synchronous equivalent.

和 zlib.createZipArchive() 一样,这些条目由返回的迭代器拥有,不能重复使用。如果迭代提前停止——包括流条目抛出异常——导致停止的条目以及其后所有排队的条目都会被处理掉,释放它们持有的任何资源。

🌐 As with zlib.createZipArchive(), the entries are owned by the returned iterator and must not be reused. If iteration stops early - including the throw on a streaming entry - the entry that stopped it and every entry still queued behind it are disposed, releasing any sources they hold.

zlib.zipFiles(files[, options])#>

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个函数)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this function among them) emits an experimental warning the first time; merely importing node:zlib does not.

  • files <Iterable> [sourcePath, entryName] 字符串对。任何可迭代对象都可以——数组、Map、Object.entries() 的结果、生成器。
  • options <string> | <Object>
    • followSymlinks <boolean> 解析符号链接并归档它所指向的文件,而不是存储链接本身。默认值: true。
    • comment <string> 一个归档评论;字符串 options 是 { comment: options } 的简写。
    • baseOffset <number> 见 zlib.createZipArchive()。
  • 返回:<stream.Readable> 由 <Buffer> 个块组成的序列化归档。

从磁盘上的文件构建一个档案。对于每个 [sourcePath, entryName] 对,它会读取 sourcePath 并添加一个名为 entryName 的条目,同时捕获文件的 Unix 模式和修改时间。目录会变成一个目录条目;普通文件的内容会以流的方式写入(作为 zlib.ZipEntry.createStream() 条目),不会在内存中缓冲。目录内容不会递归遍历——列出你想包含的每个路径。

🌐 Builds an archive from files on disk. For each [sourcePath, entryName] pair it reads sourcePath and adds an entry named entryName, capturing the file's Unix mode and modification time. A directory becomes a directory entry; a regular file's contents are streamed in (as a zlib.ZipEntry.createStream() entry) without being buffered in memory. Directory contents are not walked recursively — list each path you want included.

当 followSymlinks 是 true(默认值)时,符号链接会被解析并作为其目标文件进行归档;当它是 false 时,链接本身会被存储为一个符号链接条目,其内容是目标路径(见 zlib.ZipEntry.createSymlink())。

🌐 When followSymlinks is true (the default) a symbolic link is resolved and archived as its target file; when it is false the link itself is stored as a symbolic-link entry whose content is the target path (see zlib.ZipEntry.createSymlink()).

import { zipFiles } from 'node:zlib';
import { createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';

await pipeline(
  zipFiles([
    ['/data/report.pdf', 'report.pdf'],
    ['/data/notes.txt', 'docs/notes.txt'],
  ]),
  createWriteStream('archive.zip'),
); 

zlib.createZstdCompress([options])#>

稳定性: 1 - 实验性

  • options zstd options

创建并返回一个新的 ZstdCompress 对象。

🌐 Creates and returns a new ZstdCompress object.

zlib.createZstdDecompress([options])#>

稳定性: 1 - 实验性

  • options zstd options

创建并返回一个新的 ZstdDecompress 对象。

🌐 Creates and returns a new ZstdDecompress object.

zlib.getMaxZipContentSize()#>

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个函数)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this function among them) emits an experimental warning the first time; merely importing node:zlib does not.

当没有显式指定 maxSize 时,zipEntry.content() 当前应用的默认上限(字节)。默认值: 268435456(256 MiB)。

🌐 The current default ceiling, in bytes, applied by zipEntry.content() when no explicit maxSize is given. Default: 268435456 (256 MiB).

zlib.setMaxZipContentSize(size)#>

稳定性: 1.0 - 早期开发

ZIP 压缩档案 API 是实验性的。第一次使用它的任何部分(包括这个函数)都会发出实验性警告;仅仅导入 node:zlib 不会。

🌐 The ZIP archive API is experimental. Using any part of it (this function among them) emits an experimental warning the first time; merely importing node:zlib does not.

当没有给出明确的 maxSize 选项时,设置 zipEntry.content() 使用的默认上限。这是为了防止压缩炸弹:如果归档的中央目录声明某个成员大于此值,会在为其分配内存之前被拒绝。流式读取(zipEntry.contentIterator()、zipFile.stream())本身就是设计为有限内存的,不会受到此设置的影响。

🌐 Sets the default ceiling used by zipEntry.content() when no explicit maxSize option is given. This is a guard against zip bombs: an archive whose central directory declares a member larger than this is rejected before allocating memory for it. Streaming reads (zipEntry.contentIterator(), zipFile.stream()) are bounded-memory by design and are not affected by this setting.

便捷方法#>

🌐 Convenience methods

所有这些都将 <Buffer>、<TypedArray>、<DataView>、<ArrayBuffer> 或字符串作为第一个参数,可选的第二个参数用于向 zlib 类提供选项,并将使用 callback(error, result) 调用提供的回调函数。

🌐 All of these take a <Buffer>, <TypedArray>, <DataView>, <ArrayBuffer>, or string as the first argument, an optional second argument to supply options to the zlib classes and will call the supplied callback with callback(error, result).

每个方法都有一个 *Sync 对应方法,它们接受相同的参数,但不需要回调。

🌐 Every method has a *Sync counterpart, which accept the same arguments, but without a callback.

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

zlib.brotliCompressSync(buffer[, options])#>

使用 BrotliCompress 压缩一块数据。

🌐 Compress a chunk of data with BrotliCompress.

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

zlib.brotliDecompressSync(buffer[, options])#>

使用 BrotliDecompress 解压一块数据。

🌐 Decompress a chunk of data with BrotliDecompress.

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

zlib.deflateSync(buffer[, options])#>

使用 Deflate 压缩一块数据。

🌐 Compress a chunk of data with Deflate.

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

zlib.deflateRawSync(buffer[, options])#>

使用 DeflateRaw 压缩一块数据。

🌐 Compress a chunk of data with DeflateRaw.

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

zlib.gunzipSync(buffer[, options])#>

使用 Gunzip 解压一块数据。

🌐 Decompress a chunk of data with Gunzip.

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

zlib.gzipSync(buffer[, options])#>

使用 Gzip 压缩一块数据。

🌐 Compress a chunk of data with Gzip.

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

zlib.inflateSync(buffer[, options])#>

使用 Inflate 解压一块数据。

🌐 Decompress a chunk of data with Inflate.

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

zlib.inflateRawSync(buffer[, options])#>

使用 InflateRaw 解压一块数据。

🌐 Decompress a chunk of data with InflateRaw.

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

zlib.unzipSync(buffer[, options])#>

使用 Unzip 解压一块数据。

🌐 Decompress a chunk of data with Unzip.

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

稳定性: 1 - 实验性

zlib.zstdCompressSync(buffer[, options])#>

稳定性: 1 - 实验性

使用 ZstdCompress 压缩一块数据。

🌐 Compress a chunk of data with ZstdCompress.

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

稳定性: 1 - 实验性

zlib.zstdDecompressSync(buffer[, options])#>

稳定性: 1 - 实验性

使用 ZstdDecompress 解压一块数据。

🌐 Decompress a chunk of data with ZstdDecompress.

可迭代压缩#>

🌐 Iterable Compression

稳定性: 1 - 实验性

node:zlib/iter 模块提供压缩和解压缩转换,可用于 node:stream/iter 可迭代流 API。

🌐 The node:zlib/iter module provides compression and decompression transforms for use with the node:stream/iter iterable streams API.

此模块仅在启用 --experimental-stream-iter CLI 标志时可用。

🌐 This module is available only when the --experimental-stream-iter CLI flag is enabled.

每个算法都有一个异步版本(有状态异步生成器,用于 pull() 和 pipeTo())以及一个同步版本(有状态同步生成器,用于 pullSync() 和 pipeToSync())。

🌐 Each algorithm has both an async variant (stateful async generator, for use with pull() and pipeTo()) and a sync variant (stateful sync generator, for use with pullSync() and pipeToSync()).

异步转换在 libuv 线程池上运行压缩,将 I/O 与 JavaScript 执行重叠。同步转换直接在主线程上运行压缩。

🌐 The async transforms run compression on the libuv threadpool, overlapping I/O with JavaScript execution. The sync transforms run compression directly on the main thread.

注意:这些转换的默认设置针对流式传输吞吐量进行了优化, 并且与 node:zlib 中的默认设置不同。特别是,gzip/deflate 的默认级别为 4(而不是 6),内存级别为 9(而不是 8),而 Brotli 默认质量为 6(而不是 11)。这些选择符合常见的 HTTP 服务器配置,并在仅略微降低压缩率的情况下提供显著更快的压缩速度。所有默认设置都可以通过选项进行覆盖。

import { from, pull, bytes, text } from 'node:stream/iter';
import { compressGzip, decompressGzip } from 'node:zlib/iter';

// Async round-trip
const compressed = await bytes(pull(from('hello'), compressGzip()));
const original = await text(pull(from(compressed), decompressGzip()));
console.log(original); // 'hello'const { from, pull, bytes, text } = require('node:stream/iter');
const { compressGzip, decompressGzip } = require('node:zlib/iter');

async function run() {
  const compressed = await bytes(pull(from('hello'), compressGzip()));
  const original = await text(pull(from(compressed), decompressGzip()));
  console.log(original); // 'hello'
}

run().catch(console.error);
import { fromSync, pullSync, textSync } from 'node:stream/iter';
import { compressGzipSync, decompressGzipSync } from 'node:zlib/iter';

// Sync round-trip
const compressed = pullSync(fromSync('hello'), compressGzipSync());
const original = textSync(pullSync(compressed, decompressGzipSync()));
console.log(original); // 'hello'const { fromSync, pullSync, textSync } = require('node:stream/iter');
const { compressGzipSync, decompressGzipSync } = require('node:zlib/iter');

const compressed = pullSync(fromSync('hello'), compressGzipSync());
const original = textSync(pullSync(compressed, decompressGzipSync()));
console.log(original); // 'hello'

compressBrotli([options])#>

compressBrotliSync([options])#>

  • options <Object>
    • chunkSize <number> 输出缓冲区大小。默认值: 65536(64 KB)。
    • params <Object> 键值对象,其中键和值都是 zlib.constants 条目。最重要的压缩器参数是:
      • BROTLI_PARAM_MODE -- BROTLI_MODE_GENERIC(默认),BROTLI_MODE_TEXT,或BROTLI_MODE_FONT。
      • BROTLI_PARAM_QUALITY -- 范围从 BROTLI_MIN_QUALITY 到 BROTLI_MAX_QUALITY。默认值: 6(不是 BROTLI_DEFAULT_QUALITY,后者为 11)。质量 6 适合流式传输;质量 11 适用于离线/构建时压缩。
      • BROTLI_PARAM_SIZE_HINT -- 预期输入大小。默认值: 0 (未知)。
      • BROTLI_PARAM_LGWIN -- 窗口大小 (以 log2 为单位)。默认值: 20(1 MB)。Brotli 库的默认值是 22(4 MB);减小默认值可以在不显著影响流式工作负载压缩的情况下节省内存。
      • BROTLI_PARAM_LGBLOCK -- 输入块大小 (以2为底的对数)。 有关完整列表,请参见 zlib 文档中的 Brotli 压缩器选项。
    • dictionary <Buffer> | <TypedArray> | <DataView>
  • 返回:<Object> 有状态的变换。

创建一个 Brotli 压缩转换。输出与 zlib.brotliDecompress() 和 decompressBrotli()/decompressBrotliSync() 兼容。

🌐 Create a Brotli compression transform. Output is compatible with zlib.brotliDecompress() and decompressBrotli()/decompressBrotliSync().

compressDeflate([options])#>

compressDeflateSync([options])#>

创建一个 deflate 压缩转换。输出与 zlib.inflate() 和 decompressDeflate()/decompressDeflateSync() 兼容。

🌐 Create a deflate compression transform. Output is compatible with zlib.inflate() and decompressDeflate()/decompressDeflateSync().

compressGzip([options])#>

compressGzipSync([options])#>

创建一个 gzip 压缩转换。输出与 zlib.gunzip() 和 decompressGzip()/decompressGzipSync() 兼容。

🌐 Create a gzip compression transform. Output is compatible with zlib.gunzip() and decompressGzip()/decompressGzipSync().

compressZstd([options])#>

compressZstdSync([options])#>

  • options <Object>
    • chunkSize <number> 输出缓冲区大小。默认值: 65536(64 KB)。
    • params <Object> 键值对象,其中键和值都是 zlib.constants 条目。最重要的压缩器参数是:
      • ZSTD_c_compressionLevel -- 默认: ZSTD_CLEVEL_DEFAULT (3)。
      • ZSTD_c_checksumFlag -- 生成校验和。默认值: 0。
      • ZSTD_c_strategy -- 压缩策略。值包括 ZSTD_fast、ZSTD_dfast、ZSTD_greedy、ZSTD_lazy、ZSTD_lazy2、ZSTD_btlazy2、ZSTD_btopt、ZSTD_btultra、ZSTD_btultra2。完整列表请参见 zlib 文档中的 Zstd 压缩器选项。
    • pledgedSrcSize <number> 预期的未压缩大小,作为非负安全整数(可选提示)。
    • dictionary <Buffer> | <TypedArray> | <DataView>
  • 返回:<Object> 有状态的变换。

创建一个 Zstandard 压缩转换。输出与 zlib.zstdDecompress() 和 decompressZstd()/decompressZstdSync() 兼容。

🌐 Create a Zstandard compression transform. Output is compatible with zlib.zstdDecompress() and decompressZstd()/decompressZstdSync().

decompressBrotli([options])#>

decompressBrotliSync([options])#>

  • options <Object>
    • chunkSize <number> 输出缓冲区大小。默认值: 65536(64 KB)。
    • params <Object> 键值对象,其中键和值都是 zlib.constants 条目。可用的解压参数:
      • BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION -- 布尔值 影响内部内存分配的标志。
      • BROTLI_DECODER_PARAM_LARGE_WINDOW -- 布尔标志,用于启用“大窗口 Brotli”模式(与 RFC 7932 不兼容)。有关详细信息,请参见 zlib 文档中的 Brotli 解压缩器选项。
    • dictionary <Buffer> | <TypedArray> | <DataView>
  • 返回:<Object> 有状态的变换。

创建一个 Brotli 解压缩转换。

🌐 Create a Brotli decompression transform.

decompressDeflate([options])#>

decompressDeflateSync([options])#>

创建一个 deflate 解压缩转换。

🌐 Create a deflate decompression transform.

decompressGzip([options])#>

decompressGzipSync([options])#>

创建一个 gzip 解压缩转换。

🌐 Create a gzip decompression transform.

decompressZstd([options])#>

decompressZstdSync([options])#>

  • options <Object>
    • chunkSize <number> 输出缓冲区大小。默认值: 65536(64 KB)。
    • params <Object> 键值对象,其中键和值都是 zlib.constants 条目。可用的解压参数:
      • ZSTD_d_windowLogMax -- 解压器将分配的最大窗口大小(以2为底的对数)。用于限制恶意输入的内存使用。有关详细信息,请参阅 zlib 文档中的 Zstd 解压选项。
    • dictionary <Buffer> | <TypedArray> | <DataView>
  • 返回:<Object> 有状态的变换。

创建一个 Zstandard 解压缩转换。

🌐 Create a Zstandard decompression transform.

Node.js 中文网 - 粤ICP备13048890号