Spec-Zone.ru › Node.js 6 LTS

Zlib

Устойчивость: 2 - Стабильно

Модуль zlib предоставляет функциональность сжатия, реализованную с использованием Gzip и Deflate/Inflate. К нему можно обратиться, используя:

const zlib = require('zlib');

Сжатие или распаковку потока (например, файла) можно выполнить, передав данные исходного потока через zlib поток в целевой поток:

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 = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, (err, buffer) => {
  if (!err) {
    console.log(buffer.toString());
  } else {
    // handle error
  }
});

Сжатие HTTP-запросов и ответов

Модуль zlib может использоваться для реализации поддержки механизмов кодирования содержимого gzip и deflate, определённых в HTTP.

Заголовок HTTP Accept-Encoding используется в запросе HTTP для идентификации кодировок сжатия, поддерживаемых клиентом. Заголовок Content-Encoding используется для идентификации фактически применённых кодировок сжатия к сообщению.

Примечание: приведённые ниже примеры сильно упрощены, чтобы показать базовый принцип. Использование кодирования zlib может быть дорогостоящим, и результаты следует кэшировать. Подробнее о компромиссах между скоростью, памятью и сжатием при использовании zlib см. в разделе Настройка использования памяти.

// client request example
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'example.com',
                           path: '/',
                           port: 80,
                           headers: { 'Accept-Encoding': 'gzip,deflate' } });
request.on('response', (response) => {
  const output = fs.createWriteStream('example.com_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) => {
  const raw = fs.createReadStream('index.html');
  let 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 будут генерировать ошибку при распаковке усечённых данных. Однако, если известно, что данные неполные, или требуется просмотреть только начало сжатого файла, можно подавить обработку по умолчанию, изменив метод сброса, используемый для сжатия последней части входных данных:

// This is a truncated version of the buffer from the above examples
const buffer = Buffer.from('eJzT0yMA', 'base64');

zlib.unzip(
  buffer,
  { finishFlush: zlib.Z_SYNC_FLUSH },
  (err, buffer) => {
    if (!err) {
      console.log(buffer.toString());
    } else {
      // handle error
    }
  });

Это не изменит поведение в других ситуациях, генерирующих ошибки, например, когда входные данные имеют неверный формат. Использование этого метода не позволит определить, закончился ли входной поток преждевременно или не имеет проверок целостности, поэтому необходимо вручную проверить, что результат распаковки корректен.

Настройка использования памяти

Из zlib/zconf.h, изменённое для использования в Node.js:

Требования к памяти для deflate (в байтах):

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

То есть: 128 КБ для windowBits = 15 + 128 КБ для memLevel = 8 (значения по умолчанию) плюс несколько килобайт для небольших объектов.

Например, чтобы уменьшить значения по умолчанию с 256 КБ до 128 КБ, нужно установить:

const options = { 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);

Константы

Добавлен в: v0.5.8

Все константы, определённые в zlib.h, также определены в require('zlib'). В обычном режиме работы нет необходимости использовать эти константы. Они задокументированы, чтобы их присутствие не вызывало удивления. Этот раздел взят практически напрямую из документации zlib. Подробнее см. http://zlib.net/manual.html#Constants.

Разрешённые значения сброса.

  • zlib.Z_NO_FLUSH
  • zlib.Z_PARTIAL_FLUSH
  • zlib.Z_SYNC_FLUSH
  • zlib.Z_FULL_FLUSH
  • zlib.Z_FINISH
  • zlib.Z_BLOCK
  • zlib.Z_TREES

Коды возврата для функций сжатия/распаковки. Отрицательные значения — ошибки, положительные значения используются для особых, но нормальных событий.

  • zlib.Z_OK
  • zlib.Z_STREAM_END
  • zlib.Z_NEED_DICT
  • zlib.Z_ERRNO
  • zlib.Z_STREAM_ERROR
  • zlib.Z_DATA_ERROR
  • zlib.Z_MEM_ERROR
  • zlib.Z_BUF_ERROR
  • zlib.Z_VERSION_ERROR

Уровни сжатия.

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

Стратегия сжатия.

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

Метод сжатия deflate (единственный поддерживаемый в этой версии).

  • zlib.Z_DEFLATED

Для инициализации zalloc, zfree, opaque.

  • zlib.Z_NULL

Параметры класса

Добавлен в: v0.11.1

Каждый класс принимает объект options. Все параметры необязательны.

Обратите внимание, что некоторые параметры актуальны только при сжатии и игнорируются классами распаковки.

  • flush (по умолчанию: zlib.Z_NO_FLUSH)
  • finishFlush (по умолчанию: zlib.Z_FINISH)
  • chunkSize (по умолчанию: 16 * 1024)
  • windowBits
  • level (только для сжатия)
  • memLevel (только для сжатия)
  • strategy (только для сжатия)
  • dictionary (только для deflate/inflate, пустой словарь по умолчанию)

См. описание deflateInit2 и inflateInit2 на http://zlib.net/manual.html#Advanced для получения дополнительной информации.

Класс: zlib.Deflate

Добавлен в: v0.5.8

Сжатие данных с использованием deflate.

Класс: zlib.DeflateRaw

Добавлен в: v0.5.8

Сжатие данных с использованием deflate без добавления заголовка zlib.

Класс: zlib.Gunzip

Добавлен в: v0.5.8

Распаковка gzip-потока.

Класс: zlib.Gzip

Добавлен в: v0.5.8

Сжатие данных с использованием gzip.

Класс: zlib.Inflate

Добавлен в: v0.5.8

Распаковка deflate-потока.

Класс: zlib.InflateRaw

Добавлен в: v0.5.8

Распаковка потока raw deflate.

Класс: zlib.Unzip

Добавлен в: v0.5.8

Распаковка потока, сжатого с помощью Gzip или Deflate, автоматически определяя заголовок.

Класс: zlib.Zlib

Добавлен в: v0.5.8

Не экспортируется модулем zlib. Он документирован здесь, потому что является базовым классом для классов сжатия/распаковки.

zlib.close([callback])

Добавлен в: v0.9.4

Закрытие внутреннего дескриптора.

zlib.flush([kind], callback)

Добавлен в: v0.5.8

kind по умолчанию zlib.Z_FULL_FLUSH.

Сброс ожидающих данных. Не вызывайте это слишком часто, преждевременный сброс отрицательно влияет на эффективность алгоритма сжатия.

Этот вызов только сбрасывает данные из внутреннего состояния zlib, и не выполняет сброс на уровне потоков. Скорее, он ведёт себя как обычный вызов .write(), т. е. он будет помещён в очередь позади других ожидающих записей и произведёт вывод только при чтении данных из потока.

zlib.params(level, strategy, callback)

Добавлен в: v0.11.4

Динамическое обновление уровня сжатия и стратегии сжатия. Применимо только к алгоритму deflate.

zlib.reset()

Добавлен в: v0.7.0

Сброс сжимателя/распаковщика до заводских настроек. Применимо только к алгоритмам inflate и deflate.

zlib.constants

Добавлен в: v7.0.0

Предоставляет объект, перечисляющий константы, связанные с Zlib.

zlib.createDeflate(options)

Добавлен в: v0.5.8

Возвращает новый объект Deflate с параметрами options.

zlib.createDeflateRaw(options)

Добавлен в: v0.5.8

Возвращает новый объект DeflateRaw с параметрами options.

Примечание: Обновление zlib с 1.2.8 до 1.2.11 изменило поведение при установке windowBits в 8 для потоков raw deflate. zlib автоматически устанавливал windowBits в 9, если он изначально был равен 8. Более новые версии zlib будут генерировать исключение, поэтому Node.js восстановил исходное поведение, повышая значение 8 до 9, так как передача windowBits = 9 в zlib фактически приводит к потоку сжатия, который эффективно использует 8-битный окно только.

zlib.createGunzip(options)

Добавлен в: v0.5.8

Возвращает новый объект Gunzip с параметрами options.

zlib.createGzip(options)

Добавлен в: v0.5.8

Возвращает новый объект Gzip с параметрами options.

zlib.createInflate(options)

Добавлен в: v0.5.8

Возвращает новый объект Inflate с параметрами options.

zlib.createInflateRaw(options)

Добавлен в: v0.5.8

Возвращает новый объект InflateRaw с параметрами options.

zlib.createUnzip(options)

Добавлен в: v0.5.8

Возвращает новый объект Unzip с параметрами options.

Удобные методы

Все они принимают Buffer или строку в качестве первого аргумента, необязательный второй аргумент для задания параметров для классов zlib и вызовут предоставленную функцию обратного вызова с callback(error, result).

Каждый метод имеет *Sync аналог, который принимает те же аргументы, но без обратного вызова.

zlib.deflate(buf[, options], callback)

Добавлен в: v0.6.0

zlib.deflateSync(buf[, options])

Добавлен в: v0.11.12

Сжимает Buffer или строку с помощью Deflate.

zlib.deflateRaw(buf[, options], callback)

Добавлен в: v0.6.0

zlib.deflateRawSync(buf[, options])

Добавлен в: v0.11.12

Сжимает Buffer или строку с помощью DeflateRaw.

zlib.gunzip(buf[, options], callback)

Добавлен в: v0.6.0

zlib.gunzipSync(buf[, options])

Добавлен в: v0.11.12

Распаковывает Buffer или строку с помощью Gunzip.

zlib.gzip(buf[, options], callback)

Добавлен в: v0.6.0

zlib.gzipSync(buf[, options])

Добавлен в: v0.11.12

Сжимает Buffer или строку с помощью Gzip.

zlib.inflate(buf[, options], callback)

Добавлен в: v0.6.0

zlib.inflateSync(buf[, options])

Добавлен в: v0.11.12

Распаковывает Buffer или строку с помощью Inflate.

zlib.inflateRaw(buf[, options], callback)

Добавлен в: v0.6.0

zlib.inflateRawSync(buf[, options])

Добавлен в: v0.11.12

Распаковывает Buffer или строку с помощью InflateRaw.

zlib.unzip(buf[, options], callback)

Добавлен в: v0.6.0

zlib.unzipSync(buf[, options])

Добавлен в: v0.11.12

Распаковывает Buffer или строку с помощью 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-v6.x/docs/api/zlib.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API