2015-03-13 10 views
5

Ich schreibe einen Knotencode und benutze jszip, um einige Dateien zu komprimieren und zu entpacken. Ich weiß, wie man zippt, kann aber nicht herausfinden, wie man entpackt oder dekomprimiert. Es gibt ein paar Links auf Stackoverflow, die nicht funktionieren. Hat jemand eine Lösung? Im Anschluss an das, was ichNode.js jszip-Bibliothek zum Extrahieren

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

Antwort

7

JSZip keine Methode, um Dateien zu schreiben auf der Platte hat versucht haben. Um das zu machen, müssen Sie über zip.files iterieren:

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

Innerhalb einer ZIP-Datei, werden Ordner mit einem Schrägstrich ‚/‘ dargestellt, glaube ich dass path.join() einen richtigen Pfad erstellen, aber ich kann nicht Testen Sie dies.

0

Wahrscheinlich wegen meiner falschen Implementierung von asNodeBuffer und meiner fehlenden Erfahrung mit JS, aber ich habe die Dateien falsch extrahiert. Ich wollte teilen, was am Ende für mich funktioniert, ich habe es mit einer 250+ MB-Datei getestet.

... 
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; 
    } 
} 

Ich hoffe, das hilft.

Verwandte Themen