2015-03-13 73 views
5

我正在寫一些節點代碼,並使用jszip壓縮和解壓縮一些文件。我知道如何壓縮,但無法弄清楚如何解壓或解壓縮。在stackoverflow上有幾個鏈接不起作用。任何人都有解決辦法? 以下是我已經嘗試Node.js jszip庫提取

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

回答

7

JSZip沒有方法寫入磁盤上的文件。要做到這一點,你需要遍歷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); 
} 

裏面一個zip文件,文件夾代表正斜槓「/」,我覺得path.join()創建正確的路徑,但我不能測試這個。

0

可能是由於我錯誤地執行了asNodeBuffer以及我對JS的經驗不足,但是我一直在錯誤地提取文件。 我想分享最終爲我工作的東西,我用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; 
    } 
} 

我希望這會有所幫助。