2015-03-13 17 views
5

Tôi đang viết một số mã nút và sử dụng jszip để nén và giải nén một số tệp. Tôi biết cách nén, nhưng không thể tìm ra cách giải nén hoặc giải nén. Có một vài liên kết trên stackoverflow không hoạt động. Bất cứ ai có bất kỳ giải pháp? Sau đây là những gì tôi đã thửThư viện jszip Node.js để trích xuất

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

Trả lời

7

JSZip không có phương pháp ghi tệp trên đĩa. Để làm điều đó, bạn cần để lặp qua 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); 
} 

Bên trong một file zip, thư mục được biểu diễn với một dấu gạch chéo '/', tôi nghĩ rằng path.join() sẽ tạo ra một đường dẫn chính xác nhưng tôi không thể kiểm tra điều này.

0

Có thể là do việc triển khai sai asNodeBuffer và sự thiếu kinh nghiệm của tôi với JS, nhưng tôi đã tiếp tục trích xuất các tệp sai. Tôi muốn chia sẻ những gì cuối cùng làm việc cho tôi, tôi đã thử nghiệm nó với một tập tin 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; 
    } 
} 

Tôi hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan