Zlib
Вы можете получить доступ к этому модулю с помощью:
const zlib = require('zlib');
Это предоставляет привязки к классам Gzip/Gunzip, Deflate/Inflate и DeflateRaw/InflateRaw. Каждый класс принимает те же опции и является потоком для чтения/записи.
Примеры
Сжатие или распаковку файла можно выполнить, передав fs.ReadStream в поток zlib, а затем в fs.WriteStream.
const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');
inp.pipe(gzip).pipe(out);
Сжатие или распаковку данных в одном шаге можно выполнить, используя удобные методы.
const input = '.................................';
zlib.deflate(input, (err, buffer) => {
if (!err) {
console.log(buffer.toString('base64'));
} else {
// handle error
}
});
const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, (err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// handle error
}
});
Чтобы использовать этот модуль в HTTP-клиенте или сервере, используйте accept-encoding в запросах и заголовок content-encoding в ответах.
Примечание: эти примеры сильно упрощены, чтобы показать основной принцип. Кодирование Zlib может быть дорогостоящим, и результаты следует кэшировать. См. Настройка использования памяти для получения дополнительной информации о компромиссах между скоростью, памятью и степенью сжатия при использовании zlib.
// client request example
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'izs.me',
path: '/',
port: 80,
headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', (response) => {
var output = fs.createWriteStream('izs.me_index.html');
switch (response.headers['content-encoding']) {
// or, just use zlib.createUnzip() to handle both cases
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output);
break;
default:
response.pipe(output);
break;
}
});
// 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('zlib');
const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
var raw = fs.createReadStream('index.html');
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}
// Note: this is not a conformant accept-encoding parser.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
if (acceptEncoding.match(/\bdeflate\b/)) {
response.writeHead(200, { 'content-encoding': 'deflate' });
raw.pipe(zlib.createDeflate()).pipe(response);
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.writeHead(200, { 'content-encoding': 'gzip' });
raw.pipe(zlib.createGzip()).pipe(response);
} else {
response.writeHead(200, {});
raw.pipe(response);
}
}).listen(1337);
Настройка использования памяти
От zlib/zconf.h, изменённое для использования в node.js:
Требования к памяти для deflate (в байтах):
(1 << (windowBits+2)) + (1 << (memLevel+9))
то есть: 128 КБ для windowBits=15 + 128 КБ для memLevel = 8 (значения по умолчанию) плюс несколько килобайт для небольших объектов.
Например, если вы хотите уменьшить значения памяти по умолчанию с 256 КБ до 128 КБ, установите следующие опции:
{ windowBits: 14, memLevel: 7 }
Конечно, это, как правило, ухудшит сжатие (свободного обеда нет).
Требования к памяти для inflate (в байтах):
1 << windowBits
то есть 32 КБ для windowBits=15 (значение по умолчанию) плюс несколько килобайт для небольших объектов.
Это помимо одного внутреннего буфера выходного фрагмента размером chunkSize, который по умолчанию равен 16 КБ.
Скорость сжатия zlib наиболее сильно зависит от настройки level. Более высокое значение приведёт к лучшему сжатию, но потребует больше времени для завершения. Более низкое значение приведёт к менее эффективному сжатию, но будет значительно быстрее.
В общем случае, более высокие значения параметров использования памяти означают, что node.js должен выполнять меньше вызовов к zlib, так как сможет обрабатывать больше данных в одной write операции. Таким образом, это ещё один фактор, влияющий на скорость, но со снижением производительности при использовании большего объёма памяти.
Очистка
Вызов .flush() в потоке сжатия заставит zlib вернуть максимальное количество выходных данных. Это может привести к ухудшению качества сжатия, но может быть полезным, когда данные необходимо предоставить как можно быстрее.
В следующем примере используется flush() для записи частично сжатого HTTP-ответа клиенту:
const zlib = require('zlib');
const http = require('http');
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();
output.pipe(response);
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.h, также определены в require('zlib'). В обычном режиме работы вам не нужно будет устанавливать ни одну из них. Они документированы здесь, чтобы их присутствие не вызывало удивления. Этот раздел почти полностью взят из документации zlib. Более подробную информацию см. в http://zlib.net/manual.html#Constants.
Допустимые значения сброса.
zlib.Z_NO_FLUSHzlib.Z_PARTIAL_FLUSHzlib.Z_SYNC_FLUSHzlib.Z_FULL_FLUSHzlib.Z_FINISHzlib.Z_BLOCKzlib.Z_TREES
Коды возврата функций сжатия/распаковки. Отрицательные значения обозначают ошибки, положительные значения используются для особых, но нормальных событий.
zlib.Z_OKzlib.Z_STREAM_ENDzlib.Z_NEED_DICTzlib.Z_ERRNOzlib.Z_STREAM_ERRORzlib.Z_DATA_ERRORzlib.Z_MEM_ERRORzlib.Z_BUF_ERRORzlib.Z_VERSION_ERROR
Уровни сжатия.
zlib.Z_NO_COMPRESSIONzlib.Z_BEST_SPEEDzlib.Z_BEST_COMPRESSIONzlib.Z_DEFAULT_COMPRESSION
Стратегия сжатия.
zlib.Z_FILTEREDzlib.Z_HUFFMAN_ONLYzlib.Z_RLEzlib.Z_FIXEDzlib.Z_DEFAULT_STRATEGY
Метод сжатия deflate (единственный поддерживаемый в этой версии).
zlib.Z_DEFLATED
Для инициализации zalloc, zfree, opaque.
zlib.Z_NULL
Параметры класса
Каждый класс принимает объект с параметрами. Все параметры необязательны.
Обратите внимание, что некоторые параметры актуальны только при сжатии и игнорируются классами распаковки.
- flush (значение по умолчанию:
zlib.Z_NO_FLUSH) - chunkSize (значение по умолчанию: 16*1024)
- windowBits
- level (только для сжатия)
- memLevel (только для сжатия)
- strategy (только для сжатия)
- dictionary (только для deflate/inflate, пустой словарь по умолчанию)
См. описание deflateInit2 и inflateInit2 на http://zlib.net/manual.html#Advanced для получения дополнительной информации.
Класс: zlib.Deflate
Сжимает данные с помощью deflate.
Класс: zlib.DeflateRaw
Сжимает данные с помощью deflate и не добавляет заголовок zlib.
Класс: zlib.Gunzip
Распаковывает поток gzip.
Класс: zlib.Gzip
Сжимает данные с помощью gzip.
Класс: zlib.Inflate
Распаковывает поток deflate.
Класс: zlib.InflateRaw
Распаковывает поток raw deflate.
Класс: zlib.Unzip
Распаковывает поток, сжатый gzip или deflate, автоматически определяя заголовок.
Класс: zlib.Zlib
Не экспортируется модулем zlib. Он документирован здесь, потому что является базовым классом для классов сжатия/распаковки.
zlib.flush([kind], callback)
kind по умолчанию zlib.Z_FULL_FLUSH.
Очищает ожидающие данные. Не вызывайте это без необходимости, преждевременная очистка негативно влияет на эффективность алгоритма сжатия.
Вызов этой функции только очищает данные из внутреннего состояния zlib и не выполняет очистку на уровне потоков. Вместо этого он ведёт себя как обычный вызов .write(), т.е. он будет помещён в очередь позади других ожидающих операций записи и сгенерирует выходные данные только при чтении данных из потока.
zlib.params(level, strategy, callback)
Динамически обновляет уровень сжатия и стратегию сжатия. Применимо только к алгоритму deflate.
zlib.reset()
Сбрасывает сжатие/распаковку до значений по умолчанию. Применимо только к алгоритмам inflate и deflate.
zlib.createDeflate(options)
Возвращает новый объект Deflate с параметрами options.
zlib.createDeflateRaw(options)
Возвращает новый объект DeflateRaw с параметрами options.
Примечание: Обновление zlib с 1.2.8 до 1.2.11 изменило поведение при установке windowBits в 8 для потоков raw deflate. zlib не имеет рабочей реализации 8-битного окна для потоков raw deflate и автоматически установит windowBit в 9, если он был изначально установлен в 8. Более новые версии zlib будут генерировать исключение. Это может привести к атаке типа DoS, и поэтому поведение было восстановлено в Node.js 8, 6 и 4. Node.js версии 9 и выше будут генерировать исключение при установке windowBits в 8.
zlib.createGunzip(options)
Возвращает новый объект Gunzip с параметрами options.
zlib.createGzip(options)
Возвращает новый объект Gzip с параметрами options.
zlib.createInflate(options)
Возвращает новый объект Inflate с параметрами options.
zlib.createInflateRaw(options)
Возвращает новый объект InflateRaw с параметрами options.
zlib.createUnzip(options)
Возвращает новый объект Unzip с параметрами options.
Удобные методы
Все эти методы принимают Buffer или строку в качестве первого аргумента, необязательный второй аргумент для задания опций для классов zlib и вызывают переданный обратный вызов с callback(error, result).
Каждый метод имеет *Sync аналог, принимающий те же аргументы, но без обратного вызова.
zlib.deflate(buf[, options], callback)
zlib.deflateSync(buf[, options])
Сжимает Buffer или строку с помощью Deflate.
zlib.deflateRaw(buf[, options], callback)
id="zlib_zlib_deflaterawsync_buf_options">zlib.deflateRawSync(buf[, options])
Сжать буфер или строку с помощью DeflateRaw.
zlib.gunzip(buf[, options], callback)
id="zlib_zlib_gunzipsync_buf_options">zlib.gunzipSync(buf[, options])
Распаковать буфер или строку с помощью Gunzip.
zlib.gzip(buf[, options], callback)
zlib.gzipSync(buf[, options])
Сжать буфер или строку с помощью Gzip.
zlib.inflate(buf[, options], callback)
zlib.inflateSync(buf[, options])
Распаковать буфер или строку с помощью Inflate.
zlib.inflateRaw(buf[, options], callback)
zlib.inflateRawSync(buf[, options])
Распаковать буфер или строку с помощью InflateRaw.
zlib.unzip(buf[, options], callback)
zlib.unzipSync(buf[, 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-v4.x/docs/api/zlib.html