Tenemos el arreglo a esta cuestión, al menos eso deseamos. Si tienes interrogantes puedes escribirlo en el apartado de comentarios, para nosotros será un gusto ayudarte
Solución:
Es 2017 (26 de octubre, para ser exactos).
Para una tecnología antigua y omnipresente como descomprimir, esperaría que existiera una biblioteca de descompresión node.js bastante popular y madura que esté “estancada” y “sin mantenimiento” porque está “completa”.
Sin embargo, la mayoría de las bibliotecas parecen ser completamente terribles o tienen compromisos recientes como hace solo unos meses. Esto es bastante preocupante … así que revisé varias bibliotecas de descompresión, leí sus documentos y probé sus ejemplos para tratar de descubrir WTF. Por ejemplo, he probado estos:
- eljoshwolfe/
yauzl
- Antela/
node-stream-zip
- ZJONSSON/
node-unzipper
- EvanOxfeld/
node-unzip
- Stuk/
jszip
- kriskowal/
zip
Actualización 2020: aún no lo he probado, pero también hay un archivador
Recomendación superior: yauzl
Funciona muy bien para el archivo completamente descargado. No es tan bueno para la transmisión.
Bien documentada. Funciona bien. Tiene sentido.
2da elección: node-stream-zip
de antelle node-stream-zip
parece ser el mejor
Instalar en pc:
npm install --save node-stream-zip
Uso:
'use strict';
var fs = require('fs');
var StreamZip = require('node-stream-zip');
var zip = new StreamZip(
file: './example.zip'
, storeEntries: true
);
zip.on('error', function (err) console.error('[ERROR]', err); );
zip.on('ready', function ()
console.log('All entries read: ' + zip.entriesCount);
//console.log(zip.entries());
);
zip.on('entry', function (entry)
var pathname = path.resolve('./temp', entry.name);
if (/../.test(path.relative('./temp', pathname)))
console.warn("[zip warn]: ignoring maliciously crafted paths in zip file:", entry.name);
return;
if ('/' === entry.name[entry.name.length - 1])
console.log('[DIR]', entry.name);
return;
console.log('[FILE]', entry.name);
zip.stream(entry.name, function (err, stream)
if (err) console.error('Error:', err.toString()); return;
stream.on('error', function (err) console.log('[ERROR]', err); return; );
// example: print contents to screen
//stream.pipe(process.stdout);
// example: save contents to file
fs.mkdir(
path.dirname(pathname),
recursive: true ,
function (err)
stream.pipe(fs.createWriteStream(pathname));
);
);
);
Advertencia de seguridad:
No estoy seguro si esto comprueba entry.name
para rutas creadas con fines malintencionados que se resolverían incorrectamente (como ../../../foo
o /etc/passwd
).
Puede comprobarlo usted mismo fácilmente comparando /../.test(path.relative('./to/dir', path.resolve('./to/dir', entry.name)))
.
ventajas: (¿Por qué creo que es el mejor?)
- puede descomprimir archivos normales (quizás no algunos locos con extensiones raras)
- puede transmitir
- parece no tener que cargar todo el zip para leer las entradas
- tiene ejemplos en JavaScript normal (no compilado)
- no incluye el fregadero de la cocina (es decir, carga de URL, S3 o capas de base de datos)
- usa algún código existente de una biblioteca popular
- no tiene demasiado hipster sin sentido o ninja-foo en el código
Contras:
- Se traga los errores como un hipopótamo hambriento
- Lanza cadenas en lugar de errores (sin rastros de pila)
zip.extract()
no parece funcionar (por eso usézip.stream()
en mi ejemplo)
Subcampeón: node-unzipper
Instalar en pc:
npm install --save unzipper
Uso:
'use strict';
var fs = require('fs');
var unzipper = require('unzipper');
fs.createReadStream('./example.zip')
.pipe(unzipper.Parse())
.on('entry', function (entry)
var fileName = entry.path;
var type = entry.type; // 'Directory' or 'File'
console.log();
if (//$/.test(fileName))
console.log('[DIR]', fileName, type);
return;
console.log('[FILE]', fileName, type);
// TODO: probably also needs the security check
entry.pipe(process.stdout/*fs.createWriteStream('output/path')*/);
// NOTE: To ignore use entry.autodrain() instead of entry.pipe()
);
ventajas:
- Parece funcionar de manera similar a
node-stream-zip
pero menos control - Una horquilla más funcional de
unzip
- Parece que se ejecuta en serie en lugar de en paralelo
Contras:
- Fregadero de la cocina mucho? Solo incluye un montón de cosas que no están relacionadas con la descompresión
- Lee todo el archivo (por fragmentos, lo cual está bien), no solo búsquedas aleatorias
Echa un vistazo a adm-zip.
ADM-ZIP es una implementación de JavaScript puro para la compresión de datos zip para NodeJS.
La biblioteca le permite:
- descomprimir archivos zip directamente en el disco o en los búferes en memoria
- comprimir archivos y almacenarlos en el disco en
.zip
formato o en búferes comprimidos- actualizar el contenido de/agregar nuevos/eliminar archivos de un archivo existente
.zip
Node tiene soporte incorporado para gzip y deflate a través del módulo zlib:
var zlib = require('zlib');
zlib.gunzip(gzipBuffer, function(err, result)
if(err) return console.error(err);
console.log(result);
);
Editar: Usted puede incluso pipe
los datos directamente a través de, por ejemplo Gunzip
(usando solicitud):
var request = require('request'),
zlib = require('zlib'),
fs = require('fs'),
out = fs.createWriteStream('out');
// Fetch http://example.com/foo.gz, gunzip it and store the results in 'out'
request('http://example.com/foo.gz').pipe(zlib.createGunzip()).pipe(out);
Para los archivos tar, existe el módulo tar de Isaacs, que es utilizado por npm.
Edición 2: Respuesta actualizada como zlib
no apoya la zip
formato. Esto solo funcionará para gzip
.
Tienes la opción de añadir valor a nuestro contenido añadiendo tu veteranía en las explicaciones.