Zlib
Исходный код: lib/zlib.js
Модуль node:zlib предоставляет функциональность сжатия, реализованную с использованием Gzip, Deflate/Inflate и Brotli.
Для доступа к нему:
Модули JavaScript
import zlib from 'node:zlib';
CommonJS
const zlib = require('node:zlib');Сжатие и распаковка построены на основе API потоков Node.js.
Сжать или распаковать поток (например, файл) можно, передав исходный поток через поток zlib Transform в поток назначения:
Модули JavaScript
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;
}
});CommonJS
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;
}
});Или с помощью API pipeline для промисов:
Модули JavaScript
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');CommonJS
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;
});Также можно сжать или распаковать данные за один шаг:
Модули JavaScript
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());CommonJS
const { deflate, unzip } = require('node:zlib');
const input = '.................................';
deflate(input, (err, buffer) => {
if (err) {
console.error('An error occurred:', err);
process.exitCode = 1;
}
console.log(buffer.toString('base64'));
});
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
unzip(buffer, (err, buffer) => {
if (err) {
console.error('An error occurred:', err);
process.exitCode = 1;
}
console.log(buffer.toString());
});
// Or, Promisified
const { promisify } = require('node:util');
const do_unzip = promisify(unzip);
do_unzip(buffer)
.then((buf) => console.log(buf.toString()))
.catch((err) => {
console.error('An error occurred:', err);
process.exitCode = 1;
});Использование пула потоков и особенности производительности
Все API zlib, кроме явно синхронных, используют внутренний пул потоков Node.js. В некоторых приложениях это может приводить к неожиданным последствиям и ограничениям производительности.
Одновременное создание и использование большого количества объектов zlib может привести к значительной фрагментации памяти.
Модули JavaScript
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) => {});
}CommonJS
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 можно использовать для реализации поддержки механизмов кодирования содержимого gzip, deflate и br, определённых в HTTP.
Заголовок Accept-Encoding протокола HTTP используется в HTTP-запросе для указания алгоритмов сжатия, которые поддерживает клиент. Заголовок Content-Encoding используется для указания алгоритмов сжатия, фактически применённых к сообщению.
Приведённые ниже примеры значительно упрощены, чтобы показать основную идею. Кодирование с помощью zlib может быть затратным, поэтому результаты следует кэшировать. Дополнительные сведения о компромиссах между скоростью, памятью и сжатием при использовании zlib см. в разделе Настройка использования памяти.
Модули JavaScript
// 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;
}
});CommonJS
// 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' } });
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;
}
});Модули JavaScript
// 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);CommonJS
// 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');
let acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}
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);По умолчанию методы 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.
{ finishFlush: zlib.constants.Z_SYNC_FLUSH },
(err, buffer) => {
if (err) {
console.error('An error occurred:', err);
process.exitCode = 1;
}
console.log(buffer.toString());
}); copy Это не изменит поведение в других случаях, приводящих к ошибкам, например, если входные данные имеют неверный формат. При использовании этого метода определить, закончились ли входные данные преждевременно или в них отсутствуют проверки целостности, будет невозможно, поэтому потребуется вручную проверить корректность распакованного результата.
Настройка использования памяти
Для потоков на основе zlib
Из zlib/zconf.h, адаптировано для использования в Node.js:
Требования deflate к памяти (в байтах):
(1 << (windowBits + 2)) + (1 << (memLevel + 9)) copy
То есть 128K для windowBits = 15 + 128K для memLevel = 8 (значения по умолчанию), а также несколько килобайт для небольших объектов.
Например, чтобы уменьшить требования к памяти по умолчанию с 256K до 128K, следует задать параметры:
const options = { windowBits: 14, memLevel: 7 }; copy Однако это обычно ухудшает сжатие.
Требования inflate к памяти (в байтах) составляют 1 << windowBits. То есть 32K для windowBits = 15 (значение по умолчанию), а также несколько килобайт для небольших объектов.
Дополнительно используется один внутренний буфер для выходного блока размером chunkSize; его размер по умолчанию — 16K.
На скорость сжатия zlib сильнее всего влияет параметр level. Более высокий уровень обеспечивает лучшее сжатие, но требует больше времени. Более низкий уровень обеспечивает меньшее сжатие, но работает значительно быстрее.
В целом параметры, увеличивающие использование памяти, означают, что Node.js будет реже обращаться к zlib, так как сможет обрабатывать больше данных за одну операцию write. Таким образом, это ещё один фактор, влияющий на скорость, но требующий дополнительных затрат памяти.
Для потоков на основе Brotli
Для потоков на основе Brotli существуют эквиваленты параметров zlib, хотя диапазоны значений у этих параметров отличаются от диапазонов параметров zlib:
- Параметру
levelв zlib соответствует параметрBROTLI_PARAM_QUALITYв Brotli. - Параметру
windowBitsв zlib соответствует параметрBROTLI_PARAM_LGWINв Brotli.
Дополнительные сведения о параметрах Brotli см. ниже.
Сброс
Вызов .flush() для потока сжатия заставит zlib вернуть максимально возможный на данный момент объём данных. Это может ухудшить качество сжатия, но бывает полезно, когда данные должны быть доступны как можно скорее.
В следующем примере flush() используется для отправки клиенту частичного сжатого HTTP-ответа:
Модули JavaScript
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);CommonJS
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_FLUSHzlib.constants.Z_PARTIAL_FLUSHzlib.constants.Z_SYNC_FLUSHzlib.constants.Z_FULL_FLUSHzlib.constants.Z_FINISHzlib.constants.Z_BLOCK
Коды возврата функций сжатия и распаковки. Отрицательные значения означают ошибки, положительные используются для специальных, но штатных событий.
zlib.constants.Z_OKzlib.constants.Z_STREAM_ENDzlib.constants.Z_NEED_DICTzlib.constants.Z_ERRNOzlib.constants.Z_STREAM_ERRORzlib.constants.Z_DATA_ERRORzlib.constants.Z_MEM_ERRORzlib.constants.Z_BUF_ERRORzlib.constants.Z_VERSION_ERROR
Уровни сжатия.
zlib.constants.Z_NO_COMPRESSIONzlib.constants.Z_BEST_SPEEDzlib.constants.Z_BEST_COMPRESSIONzlib.constants.Z_DEFAULT_COMPRESSION
Стратегия сжатия.
zlib.constants.Z_FILTEREDzlib.constants.Z_HUFFMAN_ONLYzlib.constants.Z_RLEzlib.constants.Z_FIXEDzlib.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, поскольку уровень потоковой обработки затрудняет определение того, какие данные попадут в этот кадр. Кроме того, в настоящее время API Node.js не позволяет считывать эти данные.
Параметры компрессора
Для кодировщиков Brotli можно задать несколько параметров, влияющих на эффективность и скорость сжатия. Имена и значения этих параметров доступны как свойства объекта zlib.constants.
Наиболее важные параметры:
-
BROTLI_PARAM_MODE-
BROTLI_MODE_GENERIC(по умолчанию) -
BROTLI_MODE_TEXT, оптимизированный для текста UTF-8 -
BROTLI_MODE_FONT, оптимизированный для шрифтов WOFF 2.0
-
-
BROTLI_PARAM_QUALITY- Диапазон от
BROTLI_MIN_QUALITYдоBROTLI_MAX_QUALITY, значение по умолчанию —BROTLI_DEFAULT_QUALITY.
- Диапазон от
-
BROTLI_PARAM_SIZE_HINT- Целое число, представляющее ожидаемый размер входных данных; для неизвестного размера по умолчанию используется
0.
- Целое число, представляющее ожидаемый размер входных данных; для неизвестного размера по умолчанию используется
Для расширенного управления алгоритмом сжатия и настройки использования памяти можно задать следующие флаги:
-
BROTLI_PARAM_LGWIN- Диапазон от
BROTLI_MIN_WINDOW_BITSдоBROTLI_MAX_WINDOW_BITS; значение по умолчанию —BROTLI_DEFAULT_WINDOW, либо доBROTLI_LARGE_MAX_WINDOW_BITS, если задан флагBROTLI_PARAM_LARGE_WINDOW.
- Диапазон от
-
BROTLI_PARAM_LGBLOCK- Диапазон от
BROTLI_MIN_INPUT_BLOCK_BITSдоBROTLI_MAX_INPUT_BLOCK_BITS.
- Диапазон от
-
BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING- Логический флаг, снижающий степень сжатия в пользу скорости распаковки.
-
BROTLI_PARAM_LARGE_WINDOW- Логический флаг, включающий режим «Brotli с большим окном» (несовместим с форматом Brotli, стандартизованным в RFC 7932).
-
BROTLI_PARAM_NPOSTFIX- Диапазон от
0доBROTLI_MAX_NPOSTFIX.
- Диапазон от
-
BROTLI_PARAM_NDIRECT- Диапазон от
0до15 << NPOSTFIXс шагом1 << NPOSTFIX.
- Диапазон от
Параметры декомпрессора
Для управления распаковкой доступны следующие расширенные параметры:
-
BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION- Логический флаг, влияющий на внутренние схемы выделения памяти.
-
BROTLI_DECODER_PARAM_LARGE_WINDOW- Логический флаг, включающий режим «Brotli с большим окном» (несовместим с форматом Brotli, стандартизованным в RFC 7932).
Класс: Options
Каждый класс на основе zlib принимает объект options. Ни один параметр не является обязательным.
Некоторые параметры актуальны только при сжатии и игнорируются классами распаковки.
-
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> (только для deflate/inflate, по умолчанию пустой словарь) -
info<boolean> (если заданоtrue, возвращает объект сbufferиengine.) -
maxOutputLength<integer> Ограничивает размер выходных данных при использовании вспомогательных методов. По умолчанию:buffer.kMaxLength
Дополнительные сведения см. в документации deflateInit2 и inflateInit2.
Класс: BrotliOptions
Каждый класс на основе Brotli принимает объект options. Все параметры необязательны.
-
flush<integer> По умолчанию:zlib.constants.BROTLI_OPERATION_PROCESS -
finishFlush<integer> По умолчанию:zlib.constants.BROTLI_OPERATION_FINISH -
chunkSize<integer> По умолчанию:16 * 1024 -
params<Object> Объект пар «ключ — значение», содержащий индексированные параметры Brotli. -
maxOutputLength<integer> Ограничивает размер выходных данных при использовании вспомогательных методов. По умолчанию:buffer.kMaxLength
Например:
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,
},
}); copy Класс: 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.bytesRead
zlib.bytesWritten.Устаревший псевдоним для zlib.bytesWritten. Это исходное название было выбрано потому, что значение также можно было трактовать как количество байтов, прочитанных движком, однако оно не согласуется с другими потоками Node.js, в которых для значений используются эти названия.
zlib.bytesWritten
Свойство zlib.bytesWritten указывает количество байтов, записанных в движок до обработки (сжатия или распаковки, в зависимости от производного класса).
zlib.crc32(data[, value])
-
data<string> | <Buffer> | <TypedArray> | <DataView> Еслиdataявляется строкой, перед вычислением она кодируется в UTF-8. -
value<integer> Необязательное начальное значение. Должно быть 32-разрядным беззнаковым целым числом. По умолчанию:0 - Возвращает: <integer> 32-разрядное беззнаковое целое число, содержащее контрольную сумму.
Вычисляет 32-разрядную контрольную сумму циклического избыточного кода для data. Если задано value, оно используется как начальное значение контрольной суммы; в противном случае начальным значением является 0.
Алгоритм CRC предназначен для вычисления контрольных сумм и обнаружения ошибок при передаче данных. Он не подходит для криптографической аутентификации.
Для согласованности с другими API строковое значение data перед вычислением кодируется в UTF-8. Если для вычисления и сравнения контрольных сумм используется только Node.js, это хорошо работает с другими API, которые по умолчанию используют кодировку UTF-8.
Некоторые сторонние библиотеки JavaScript вычисляют контрольную сумму строки на основе str.charCodeAt(), чтобы их можно было запускать в браузерах. Если нужно сравнить контрольную сумму с результатом такой библиотеки в браузере, лучше использовать ту же библиотеку в Node.js, если она также работает в Node.js. Если для сравнения контрольной суммы, полученной такой сторонней библиотекой, необходимо использовать zlib.crc32():
- Если библиотека принимает
Uint8Arrayна вход, используйте в браузереTextEncoderдля кодирования строки вUint8Arrayс кодировкой UTF-8 и вычисляйте контрольную сумму на основе строки, закодированной в UTF-8. - Если библиотека принимает только строку и вычисляет данные на основе
str.charCodeAt(), в Node.js преобразуйте строку в буфер с помощьюBuffer.from(str, 'utf16le').
Модули JavaScript
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); // 4150509955CommonJS
const 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.close([callback])
-
callback<Function>
Закрывает базовый дескриптор.
zlib.flush([kind, ]callback)
-
kindПо умолчанию:zlib.constants.Z_FULL_FLUSHдля потоков на основе zlib,zlib.constants.BROTLI_OPERATION_FLUSHдля потоков на основе Brotli. -
callback<Function>
Сбрасывает ожидающие данные. Не вызывайте этот метод без необходимости: преждевременный сброс отрицательно влияет на эффективность алгоритма сжатия.
Этот вызов сбрасывает данные только из внутреннего состояния zlib и не выполняет сброс на уровне потоков. Вместо этого он ведёт себя как обычный вызов .write(): вызов будет помещён в очередь за другими ожидающими операциями записи и выдаст результат только при чтении данных из потока.
zlib.params(level, strategy, callback)
-
level<integer> -
strategy<integer> -
callback<Function>
Эта функция доступна только для потоков на основе zlib, то есть не для Brotli.
Динамически изменяет уровень и стратегию сжатия. Применима только к алгоритму deflate.
zlib.reset()
Сбрасывает компрессор/декомпрессор до заводских настроек. Применимо только к алгоритмам inflate и deflate.
zlib.constants
Предоставляет объект с перечислением констант, связанных с Zlib.
zlib.createBrotliCompress([options])
-
options<параметры brotli>
Создаёт и возвращает новый объект BrotliCompress.
zlib.createBrotliDecompress([options])
-
options<параметры brotli>
Создаёт и возвращает новый объект BrotliDecompress.
zlib.createDeflate([options])
-
options<параметры zlib>
Создаёт и возвращает новый объект Deflate.
zlib.createDeflateRaw([options])
-
options<параметры zlib>
Создаёт и возвращает новый объект DeflateRaw.
При обновлении zlib с версии 1.2.8 до 1.2.11 поведение изменилось, когда для windowBits в потоках raw deflate задавалось значение 8. zlib автоматически устанавливал windowBits в значение 9, если изначально было задано 8. Более новые версии zlib выдают исключение, поэтому Node.js восстановил исходное поведение, при котором значение 8 повышается до 9, поскольку передача windowBits = 9 в zlib фактически приводит к созданию сжатого потока, использующего окно размером только 8 бит.
zlib.createGunzip([options])
-
options<параметры zlib>
Создаёт и возвращает новый объект Gunzip.
zlib.createGzip([options])
-
options<параметры zlib>
zlib.createInflate([options])
-
options<zlib options>
Создает и возвращает новый объект Inflate.
zlib.createInflateRaw([options])
-
options<zlib options>
Создает и возвращает новый объект InflateRaw.
zlib.createUnzip([options])
-
options<zlib options>
Создает и возвращает новый объект Unzip.
Вспомогательные методы
Все эти методы принимают в качестве первого аргумента Buffer, TypedArray, DataView, ArrayBuffer или строку, необязательный второй аргумент для передачи параметров классам zlib и вызывают предоставленную функцию обратного вызова с callback(error, result).
Для каждого метода существует вариант *Sync, который принимает те же аргументы, но без функции обратного вызова.
zlib.brotliCompress(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<brotli options> -
callback<Function>
zlib.brotliCompressSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<brotli options>
Сжимает фрагмент данных с помощью BrotliCompress.
zlib.brotliDecompress(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<brotli options> -
callback<Function>
zlib.brotliDecompressSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<brotli options>
Распаковывает фрагмент данных с помощью BrotliDecompress.
zlib.deflate(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.deflateSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Сжимает фрагмент данных с помощью Deflate.
zlib.deflateRaw(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.deflateRawSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Сжимает фрагмент данных с помощью DeflateRaw.
zlib.gunzip(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.gunzipSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Распаковывает фрагмент данных с помощью Gunzip.
zlib.gzip(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.gzipSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Сжимает фрагмент данных с помощью Gzip.
zlib.inflate(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.inflateSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Распаковывает фрагмент данных с помощью Inflate.
zlib.inflateRaw(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.inflateRawSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Распаковывает фрагмент данных с помощью InflateRaw.
zlib.unzip(buffer[, options], callback)
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options> -
callback<Function>
zlib.unzipSync(buffer[, options])
-
buffer<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string> -
options<zlib options>
Распаковывает фрагмент данных с помощью Unzip.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v20.x/docs/api/zlib.html