Il suffit de chercher une solution simple pour télécharger et décompresser les fichiers .zip
ou .tar.gz
dans Node.js sur n’importe quel système d’exploitation.
Je ne sais pas si cela est intégré ou je dois utiliser une bibliothèque séparée. Des idées? Vous cherchez juste quelques lignes de code alors quand le prochain fichier zip vient que je veux télécharger dans le nœud, c’est une évidence. Sentez-vous que cela devrait être facile et / ou intégré, mais je ne trouve rien. Merci!
Commander adm-zip .
ADM-ZIP est une implémentation purement JavaScript pour la compression des données zip pour NodeJS.
La bibliothèque vous permet de:
- décompresser les fichiers zip directement sur le disque ou les tampons en mémoire
- compresser des fichiers et les stocker sur disque au format
.zip
ou dans des tampons compressés- mettre à jour le contenu de / append de nouveaux fichiers / supprimer des fichiers existants
.zip
Node prend en charge gzip et deflate via le module zlib :
var zlib = require('zlib'); zlib.gunzip(gzipBuffer, function(err, result) { if(err) return console.error(err); console.log(result); });
Edit: Vous pouvez même Gunzip
les données directement via eg Gunzip
(à l’aide de request ):
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);
Pour les archives tar, il existe le module tar Isaacs, utilisé par npm.
Edit 2: réponse mise à jour car zlib
ne supporte pas le format zip
. Cela ne fonctionnera que pour gzip
.
C’est 2017 (le 26 octobre, pour être exact).
Pour une technologie ancienne et omniprésente telle que la décompression, je m’attendrais à ce qu’il existe une bibliothèque de décompression node.js assez populaire et mature qui soit “stagnante” et “non maintenue” car elle est “complète”.
Cependant, la plupart des bibliothèques semblent être complètement horribles ou avoir commis récemment comme il y a quelques mois. C’est assez préoccupant … j’ai donc parcouru plusieurs bibliothèques de décompression, lu leurs documents et essayé leurs exemples pour essayer de comprendre WTF. Par exemple, j’ai essayé ceux-ci:
yauzl
node-stream-zip
node-unzipper
node-unzip
jszip
zip
yauzl
Fonctionne parfaitement pour les fichiers complètement téléchargés. Pas aussi bien pour le streaming.
Bien documenté. Fonctionne bien. Logique.
node-stream-zip
antelle- node-stream-zip
semble être le meilleur
Installer:
npm install --save node-stream-zip
Usage:
'use ssortingct'; var StreamZip = require('node-stream-zip'); var zip = new StreamZip({ file: './example.zip' , storeEnsortinges: true }); zip.on('error', function (err) { console.error('[ERROR]', err); }); zip.on('ready', function () { console.log('All ensortinges read: ' + zip.ensortingesCount); //console.log(zip.ensortinges()); }); 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.toSsortingng()); 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 mkdirp(path.dirname(pathname, function (err) { stream.pipe(fs.createWriteStream(pathname)); }); }); });
Avertissement de sécurité :
Vous ne savez pas si cela vérifie entry.name
pour les chemins conçus de manière malveillante qui seraient résolus de manière incorrecte (tels que ../../../foo
ou /etc/passwd
).
Vous pouvez facilement vérifier cela vous-même en comparant /\.\./.test(path.relative('./to/dir', path.resolve('./to/dir', entry.name)))
.
Avantages : (Pourquoi est-ce que je pense que c’est le meilleur?)
Contre :
zip.extract()
ne semble pas fonctionner (j’ai donc utilisé zip.stream()
dans mon exemple) Installer:
npm install --save unzipper
Usage:
'use ssortingct'; 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() });
Avantages :
node-stream-zip
, mais moins de contrôle unzip
plus fonctionnelle Contre :
yauzl est une bibliothèque robuste pour la décompression. Principes de conception:
A présent une couverture de test de 97%.
J’ai essayé quelques-unes des bibliothèques de décompression de nodejs, y compris adm-zip et unzip, puis installé sur extract-zip qui est un wrapper autour de yauzl. Semble le plus simple à mettre en œuvre.
https://www.npmjs.com/package/extract-zip
var extract = require('extract-zip') extract(zipfile, { dir: outputPath }, function (err) { // handle err })
J’attendais cela depuis longtemps et je n’ai trouvé aucun exemple de travail simple, mais sur la base de ces réponses, j’ai créé la fonction downloadAndUnzip()
.
L’utilisation est assez simple:
downloadAndUnzip('http://your-domain.com/archive.zip', 'yourfile.xml') .then(function (data) { console.log(data); // unzipped content of yourfile.xml in root of archive.zip }) .catch(function (err) { console.error(err); });
Et voici la déclaration:
var AdmZip = require('adm-zip'); var request = require('request'); var downloadAndUnzip = function (url, fileName) { /** * Download a file * * @param url */ var download = function (url) { return new Promise(function (resolve, reject) { request({ url: url, method: 'GET', encoding: null }, function (err, response, body) { if (err) { return reject(err); } resolve(body); }); }); }; /** * Unzip a Buffer * * @param buffer * @returns {Promise} */ var unzip = function (buffer) { return new Promise(function (resolve, reject) { var resolved = false; var zip = new AdmZip(buffer); var zipEnsortinges = zip.getEnsortinges(); // an array of ZipEntry records zipEnsortinges.forEach(function (zipEntry) { if (zipEntry.entryName == fileName) { resolved = true; resolve(zipEntry.getData().toSsortingng('utf8')); } }); if (!resolved) { reject(new Error('No file found in archive: ' + fileName)); } }); }; return download(url) .then(unzip); };
Un autre exemple de travail:
var zlib = require('zlib'); var tar = require('tar'); var ftp = require('ftp'); var files = []; var conn = new ftp(); conn.on('connect', function(e) { conn.auth(function(e) { if (e) { throw e; } conn.get('/tz/tzdata-latest.tar.gz', function(e, stream) { stream.on('success', function() { conn.end(); console.log("Processing files ..."); for (var name in files) { var file = files[name]; console.log("filename: " + name); console.log(file); } console.log("OK") }); stream.on('error', function(e) { console.log('ERROR during get(): ' + e); conn.end(); }); console.log("Reading ..."); stream .pipe(zlib.createGunzip()) .pipe(tar.Parse()) .on("entry", function (e) { var filename = e.props["path"]; console.log("filename:" + filename); if( files[filename] == null ) { files[filename] = ""; } e.on("data", function (c) { files[filename] += c.toSsortingng(); }) }); }); }); }) .connect(21, "ftp.iana.org");
J’ai trouvé le succès avec ce qui suit, travaille avec .zip
(Simplifié ici pour la publication: pas de vérification des erreurs et il suffit de décompresser tous les fichiers dans le dossier actuel)
function DownloadAndUnzip(URL){ var unzip = require('unzip'); var http = require('http'); var request = http.get(URL, function(response) { response.pipe(unzip.Extract({path:'./'})) }); }
Vous pouvez simplement extraire les fichiers zip existants également en utilisant “unzip”. Cela fonctionnera pour tous les fichiers de taille.
fs.createReadStream(filePath).pipe(unzip.Extract({path:moveIntoFolder})).on('close', function(){ //To do after unzip callback(); });