2015-03-13 29 views
5

Piszę kod węzła i za pomocą jszip rozpakowuję i rozpakowuję niektóre pliki. Wiem, jak skompresować, ale nie mogę się dowiedzieć, jak rozpakować lub rozpakować. Istnieje kilka linków na stackoverflow, które nie działają. Ktoś ma jakieś rozwiązanie? obserwuję to co próbowałemBiblioteka jszip programu Node.js do wypakowania

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

Odpowiedz

7

JSZip ma metodę zapisu plików na dysku. Aby to zrobić, trzeba iteracyjne nad 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); 
} 

Wewnątrz pliku zip, foldery są reprezentowane za pomocą ukośnika „/”, myślę że path.join() stworzy właściwą ścieżkę, ale nie mogę przetestuj to.

0

Prawdopodobnie wynikało to z mojej błędnej implementacji asNodeBuffer i mojego braku doświadczenia z JS, ale ciągle wyodrębniałem pliki błędnie. Chciałem podzielić się tym, co ostatecznie działa dla mnie, przetestowałem go z plikiem 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; 
    } 
} 

Mam nadzieję, że to pomoże.