2011-10-02 23 views
18

¿Puede alguien explicarme cómo funciona la biblioteca zlib en Nodejs?Compresión y descompresión de datos usando zlib en Nodejs

Soy bastante nuevo en Nodejs, y todavía no estoy seguro de cómo usar búferes y secuencias.

Mi escenario simple es una variable de cadena, y quiero comprimir o descomprimir (desinflar o inflar, gzip o gunzip, etc.) la cadena a otra cadena.

I.e. (Cómo iba a esperar que funcione)

var zlib = require('zlib'); 
var str = "this is a test string to be zipped"; 
var zip = zlib.Deflate(str); // zip = [object Object] 
var packed = zip.toString([encoding?]); // packed = "packedstringdata" 
var unzipped = zlib.Inflate(packed); // unzipped = [object Object] 
var newstr = unzipped.toString([again - encoding?]); // newstr = "this is a test string to be zipped"; 

Gracias por la ayuda :)

+0

enlace a la documentación zlib nodejs: http://nodejs.org/docs/v0.5.8/api /zlib.html – Eli

Respuesta

19

actualización: No nos dimos cuenta que había un nuevo módulo integrado 'zlib' en el nodo de 0,5. Mi respuesta a continuación es para el tercero node-zlib module. Actualizará la respuesta para la versión incorporada momentáneamente.

Actualización 2: Parece que puede haber un problema con el 'zlib' incorporado. El código de muestra en los documentos no funciona para mí. El archivo resultante no es gunzip'able (falla con "final de archivo inesperado" para mí). Además, la API de ese módulo no es especialmente adecuada para lo que estás tratando de hacer. Es más para trabajar con flujos en lugar de buffers, mientras que el módulo node-zlib tiene una API más simple que es más fácil de usar para Buffers.


Un ejemplo de desinflar e inflar, usando tercera módulo de nodo-zlib partido: Respuesta

$ node 

> // Load zlib and create a buffer to compress 
> var zlib = require('zlib'); 
> var input = new Buffer('lorem ipsum dolor sit amet', 'utf8') 

> // What's 'input'? 
> input 
<Buffer 6c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74> 

> // Compress it 
> zlib.deflate(input) 
<SlowBuffer 78 9c cb c9 2f 4a cd 55 c8 2c 28 2e cd 55 48 c9 cf c9 2f 52 28 ce 2c 51 48 cc 4d 2d 01 00 87 15 09 e5> 

> // Compress it and convert to utf8 string, just for the heck of it 
> zlib.deflate(input).toString('utf8') 
'x???/J?U?,(.?UH???/R(?,QH?M-\u0001\u0000?\u0015\t?' 

> // Compress, then uncompress (get back what we started with) 
> zlib.inflate(zlib.deflate(input)) 
<SlowBuffer 6c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74> 

> // Again, and convert back to our initial string 
> zlib.inflate(zlib.deflate(input)).toString('utf8') 
'lorem ipsum dolor sit amet' 
+0

Cualquier posibilidad de obtener una introducción a las secuencias y las tuberías (¿cómo se crean/utilizan)? :) ¡Excelente respuesta, gracias! – Eli

+0

Lo sentimos, realmente no tenemos el tiempo (y no estamos demasiado familiarizados con la API de tuberías). ¿Probablemente es mejor dejarlo para una pregunta separada de todos modos? – broofa

+0

Tenga en cuenta que esta es una publicación anterior;) John Resig armó un gran sitio para jugar con Node Streams. http://ejohn.org/blog/node-js-stream-playground/ Espero que esto ayude a alguien en una situación similar. – arcseldon

0

de broofa es grande, y eso es exactamente cómo me como cosas para trabajar. Para mí, el nodo insistió en las devoluciones de llamadas. Esto terminó pareciéndose a:

var zlib = require('zlib'); 
var input = new Buffer('lorem ipsum dolor sit amet', 'utf8') 


zlib.deflate(input, function(err, buf) { 
    console.log("in the deflate callback:", buf); 

    zlib.inflate(buf, function(err, buf) { 
      console.log("in the inflate callback:", buf); 
      console.log("to string:", buf.toString("utf8")); 
    }); 

}); 

que da:

in the deflate callback: <Buffer 78 9c cb c9 2f 4a cd 55 c8 2c 28 2e cd 55 48 c9 cf c9 2f 52 28 ce 2c 51 48 cc 4d 2d 01 00 87 15 09 e5> 
in the inflate callback: <Buffer 6c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 20 61 6d 65 74> 
to string: lorem ipsum dolor sit amet 
22

Para cualquiera tropezar con esto en 2016 (y también preguntarse cómo serializar datos comprimidos a una cadena en lugar de un archivo o un tampón) - se ve como zlib (desde el nodo 0,11) ahora ofrece versiones síncronas de sus funciones que no requieren devoluciones de llamada:

var zlib = require('zlib'); 
var input = "Hellow world"; 

var deflated = zlib.deflateSync(input).toString('base64'); 
var inflated = zlib.inflateSync(new Buffer(deflated, 'base64')).toString(); 

console.log(inflated); 
+0

¿Por qué es necesaria la conversión a 'base64'? –

+4

Para ser sincero, no sé, esa es una solución a la que he llegado después de un día de experimentación. Sin 'base64' descomprimir se quejaría de los encabezados faltantes o incorrectos. Supongo que algunos personajes de control no se serializan correctamente en una cadena nativa. Tenga en cuenta que si está comprimiendo a una red o una secuencia de archivos, no debería necesitar 'base64'. – Maksym

+0

¿Por qué se infla una función asíncrona si la entrada es un búfer? P.ej.¿Por qué necesitamos una variante inflateSync? – Kevin