2011-10-02 7 views
18

Qualcuno può spiegarmi come funziona la libreria zlib in Nodejs?Compressione e decompressione dei dati utilizzando zlib in Nodejs

Sono abbastanza nuovo su Nodejs e non sono ancora sicuro di come utilizzare i buffer e gli stream.

Il mio semplice scenario è una variabile stringa, e voglio comprimere o decomprimere (sgonfiare o gonfiare, gzip o gunzip, ecc.) La stringa su un'altra stringa.

I.e. (Come mi aspetto che funzioni)

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"; 

Grazie per gli aiuti :)

+0

link al Nodejs documentazione zlib: http://nodejs.org/docs/v0.5.8/api /zlib.html – Eli

risposta

19

Aggiornamento: Non sapevamo ci fosse un nuovo modulo integrato 'zlib' nel nodo 0.5. La mia risposta qui sotto è per la terza parte node-zlib module. Aggiornerà momentaneamente la risposta per la versione integrata.

Aggiornamento 2: Sembra che possa esserci un problema con il "zlib" incorporato. Il codice di esempio nei documenti non funziona per me. Il file risultante non è gunzipabile (non funziona con "end end of file" per me). Inoltre, l'API di quel modulo non è particolarmente adatta per ciò che stai cercando di fare. È più per lavorare con gli stream che con i buffer, mentre il modulo node-zlib ha un'API più semplice che è più facile da usare per i buffer.


Un esempio di deflazione e di gonfiaggio, utilizzando 3 ° modulo nodo-zlib partito: risposta

$ 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

Qualche possibilità di ottenere un'introduzione agli stream e ai pipe (come vengono creati/utilizzati)? :) Ottima risposta, grazie! – Eli

+0

Scusa, non ho davvero il tempo (e non ho molta familiarità con l'API pipe). Probabilmente andrà meglio per una domanda SO separata? – broofa

+0

Realizza che questo è un vecchio post;) John Resig ha creato un ottimo sito per giocare con i Node Stream. http://ejohn.org/blog/node-js-stream-playground/ Spero che questo aiuti qualcuno in situazioni simili. – arcseldon

0

di broofa è grande, e questo è esattamente come avrei come cose su cui lavorare. Per me il nodo ha insistito sui callback. Questo ha finito per assomigliare:

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")); 
    }); 

}); 

che dà:

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

Per qualcuno inciampare su questo nel 2016 (e anche chiedendo come serializzare i dati compressi in una stringa piuttosto che un file o di un buffer) - sembra zlib (dal nodo 0,11) ora fornisce versioni sincrone delle sue funzioni che non richiedono callback:

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

Perché è necessaria la conversione in 'base64'? –

+4

Ad essere sincero, non lo so, questa è una soluzione alla quale sono arrivato dopo una giornata di sperimentazione. Senza 'base64' decomprimere si lamenterebbero di intestazioni mancanti o errate. Immagino che alcuni caratteri di controllo non vengano serializzati correttamente in una stringa nativa. Nota che se stai comprimendo in una rete o in un flusso di file, non dovresti aver bisogno di 'base64'. – Maksym

+0

perché si gonfia una funzione asincrona se l'ingresso è un buffer? Per esempio.perché abbiamo anche bisogno di una variante di inflateSync? – Kevin