示例

压缩或解压缩一个文件可以通过导流一个 fs.ReadStream 到一个 zlib 流,然后到一个 fs.WriteStream 来完成。

  1. const gzip = zlib.createGzip();
  2. const fs = require('fs');
  3. const inp = fs.createReadStream('input.txt');
  4. const out = fs.createWriteStream('input.txt.gz');
  5. inp.pipe(gzip).pipe(out);

一步压缩或解压缩数据可以通过快捷方法来完成。

  1. const input = '.................................';
  2. zlib.deflate(input, (err, buffer) => {
  3. if (!err) {
  4. console.log(buffer.toString('base64'));
  5. } else {
  6. // handle error
  7. }
  8. });
  9. const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
  10. zlib.unzip(buffer, (err, buffer) => {
  11. if (!err) {
  12. console.log(buffer.toString());
  13. } else {
  14. // handle error
  15. }
  16. });

要在 HTTP 客户端或服务器中使用此模块,请在请求中使用 accept-encoding 和在响应中使用 content-encoding 头。

注意:这些例子只是极其简单地展示了基础的概念。Zlib 编码消耗非常大,其结果应当被缓存。详见 优化内存占用 中更多的关于 Zlib 用法中对速度 / 内存 / 压缩的权衡取舍。

  1. // client request example
  2. const zlib = require('zlib');
  3. const http = require('http');
  4. const fs = require('fs');
  5. const request = http.get({
  6. host: 'izs.me',
  7. path: '/',
  8. port: 80,
  9. headers: {
  10. 'accept-encoding': 'gzip,deflate'
  11. }
  12. });
  13. request.on('response', (response) => {
  14. var output = fs.createWriteStream('izs.me_index.html');
  15. switch (response.headers['content-encoding']) {
  16. // or, just use zlib.createUnzip() to handle both cases
  17. case 'gzip':
  18. response.pipe(zlib.createGunzip()).pipe(output);
  19. break;
  20. case 'deflate':
  21. response.pipe(zlib.createInflate()).pipe(output);
  22. break;
  23. default:
  24. response.pipe(output);
  25. break;
  26. }
  27. });
  28. // server example
  29. // Running a gzip operation on every request is quite expensive.
  30. // It would be much more efficient to cache the compressed buffer.
  31. const zlib = require('zlib');
  32. const http = require('http');
  33. const fs = require('fs');
  34. http.createServer((request, response) => {
  35. var raw = fs.createReadStream('index.html');
  36. var acceptEncoding = request.headers['accept-encoding'];
  37. if (!acceptEncoding) {
  38. acceptEncoding = '';
  39. }
  40. // Note: this is not a conformant accept-encoding parser.
  41. // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  42. if (acceptEncoding.match(/\bdeflate\b/)) {
  43. response.writeHead(200, {
  44. 'content-encoding': 'deflate'
  45. });
  46. raw.pipe(zlib.createDeflate()).pipe(response);
  47. } else if (acceptEncoding.match(/\bgzip\b/)) {
  48. response.writeHead(200, {
  49. 'content-encoding': 'gzip'
  50. });
  51. raw.pipe(zlib.createGzip()).pipe(response);
  52. } else {
  53. response.writeHead(200, {});
  54. raw.pipe(response);
  55. }
  56. }).listen(1337);

默认情况下,Zlib 方法在截断解压缩数据时,会抛出一个错误。然而,如果已知该数据是不完整的,或仅仅是希望检查一个压缩文件的开始部分,通过改变用于压缩输入数据最后一个数据块的 flushing 方法,有可能可以抑制默认的错误处理程序:

  1. // This is a truncated version of the buffer from the above examples
  2. const buffer = new Buffer('eJzT0yMA', 'base64');
  3. zlib.unzip(buffer, {
  4. finishFlush: zlib.Z_SYNC_FLUSH
  5. }, (err, buffer) => {
  6. if (!err) {
  7. console.log(buffer.toString());
  8. } else {
  9. // handle error
  10. }
  11. });

这不会改变其他情况下抛出错误的行为,例如,当输入无效格式的数据。使用该方法,这将不可能确定输入是否提前结束或是否缺乏完整性检查,因此有必要手动检查该解压缩结果的有效性。