2015-03-13 17 views
5

Sto scrivendo un codice nodo e utilizzando jszip per comprimere e decomprimere alcuni file. So come zip, ma non riesco a capire come decomprimere, o decomprimere. Ci sono un paio di link su StackOverflow che non funzionano. Qualcuno ha qualche soluzione? seguito è quello che ho cercatoLibreria jszip Node.js per estrarre

var fs = require('fs'); 
var JSZip = require('jszip'); 
var zipName = "C:/test.zip"; 
var unzip = "C:/unzip"; 


fs.readFile(zipName, function (err, data) { 
    if (err) throw err; 
    var zip = new JSZip(); 
    zip.folder(unzip).load(data); 
}); 

risposta

7

JSZip non ha un metodo per scrivere i file sul disco. Per farlo, è necessario iterare zip.files:

var path = require("path"); 
Object.keys(zip.files).forEach(function(filename) { 
    var content = zip.files[filename].asNodeBuffer(); 
    var dest = path.join(unzip, filename); 
    fs.writeFileSync(dest, content); 
} 

all'interno di un file zip, le cartelle sono rappresentate con una barra '/', io penso che path.join() creerà un percorso corretto, ma io non posso prova questo

0

Probabilmente era dovuto alla mia errata implementazione di asNodeBuffer e alla mia mancanza di esperienza con JS, ma ho continuato a estrarre i file in modo errato. Volevo condividere ciò che funzionava per me, l'ho testato con un file 250+ MB.

... 
fs.readFile(tmpFilePath, function (err, data) { 
    if (err) { 
     throw err; 
    } 
    logger.debug('[method] Before extracting file...'); 
    JSZip.loadAsync(data).then(function (zip) { 
     var files = Object.keys(zip.files); 
     logger.debug('[method] files to be created ' + files.length); 
     // in my case, the folders where not being created while "inflating" the content. created the folders in a separated loop 
     // O(n) for those geeks on complexity. 
     createDirectories(files); 
     createFiles(files, zip, someOtherFunctionReference); 
    }).catch(function (err) { 
     deferred.reject(err); 
    }); 
}); 
... 

/** 
* Sync opperation to create the folders required for the files. 
* @param files 
*/ 
function createDirectories(files) { 
    files.forEach(function (filename) { 
     var dest = path.join(folderName, filename); 
     ensureDirectoryExistence(dest); 
    }); 
} 

/** 
* recursive create directory function 
* @param filePath 
* @returns {boolean} 
*/ 
function ensureDirectoryExistence(filePath) { 
    var dirname = path.dirname(filePath); 
    if (fs.existsSync(dirname)) { 
     return true; 
    } 
    ensureDirectoryExistence(dirname); 
    fs.mkdirSync(dirname); 
} 

/** 
* Create files sync or blocking 
* @param files 
* @param zip 
* @param cb 
*/ 
function createFiles(files, zip, cb) { 
    try { 
     var countFilesCreated = 0; 
     files.forEach(function (filename) { 
      var dest = path.join(folderName, filename); 
      // skip directories listed 
      if (dest.charAt(dest.length - 1) === '/') { 
       countFilesCreated++; 
       return; 
      } 
      return zip.file(filename).async('nodebuffer').then(function(content){ 
       // var content = zip.files[filename].nodeStream(); 
       fs.writeFileSync(dest, content); 
       countFilesCreated++; 
       // proably someone with more experience in JS can implement a promice like solution. 
       // I thought that in here instead of the counter we coud use an indexOf to return an error in case not all the elements where created correctly. 
       // but if a file throw an error, its handled by the catch ... 
       if (countFilesCreated >= files.length) { 
        logger.debug('All files created!!'); 
        cb(); 
       } 
      }); 
     }); 
    } catch (err) { 
     throw err; 
    } 
} 

Spero che questo aiuti.