2014-02-24 72 views
8

安裝過程正在下載.tar.gz存檔,然後將文件解壓縮到目標目錄。但是,並非所有文件都是必需的,我想指定哪些文件應該被提取。天真的方法是在提取後刪除不必要的文件,但我想要一個「更乾淨」的方式,而不是過濾掉。Node.js:指定要使用zlib + tar解壓縮的文件

這可能嗎?

的(相關)的代碼,我到目前爲止的(剝離的可讀性)

var fs = require('fs'); 
var tar = require('tar'); 
var zlib = require('zlib'); 

var log = console.log; 

var tarball = 'path/to/downloaded/archive.tar.gz'; 
var dest = 'path/to/destination'; 

fs.createReadStream(tarball) 
    .on("error", log) 
    .pipe(zlib.Unzip()) 
    .pipe(tar.Extract({ path: dest })) 
    .on("end", log); 

謝謝。

回答

10

它的工作原理類似於unzip模塊:

var fs = require('fs'); 
var tar = require('tar'); 
var zlib = require('zlib'); 
var path = require('path'); 
var mkdirp = require('mkdirp'); // used to create directory tree 

var log = console.log; 

var tarball = 'path/to/downloaded/archive.tar.gz'; 
var dest = 'path/to/destination'; 

fs.createReadStream(tarball) 
    .on('error', log) 
    .pipe(zlib.Unzip()) 
    .pipe(tar.Parse()) 
    .on('entry', function(entry) { 
    if (/\.js$/.test(entry.path)) { // only extract JS files, for instance 
     var isDir  = 'Directory' === entry.type; 
     var fullpath = path.join(dest, entry.path); 
     var directory = isDir ? fullpath : path.dirname(fullpath); 

     mkdirp(directory, function(err) { 
     if (err) throw err; 
     if (! isDir) { // should really make this an `if (isFile)` check... 
      entry.pipe(fs.createWriteStream(fullpath)); 
     } 
     }); 
    } 
    }); 
+0

工程就像一個魅力! –

+0

你迷惑檢查類型目錄。我編輯了答案。 – rynop

+0

@rynop好抓,雖然我會在調用'mkdirp()'之前執行該檢查。 – robertklep

0

您可以查看this post以找到一個好的解決方案。

順便說一下,在zlib-documentation中,您會看到可以指定一個調用.unzip()的「緩衝區」。

+0

沒有,存檔可能相當大,我不希望分配那麼多內存。內存佔用空間必須最小。此外,檔案包含一個目錄結構,你提出的建議不適用。 –

+0

我必須從tar讀取解壓縮的文件。我應該何時打電話給我的閱讀功能?我嘗試了關閉,但我的文件沒有完全寫在那裏。你可以看到我的代碼。 –

+0

fs.createReadStream(文件名) \t \t .pipe(zlib.Unzip()) \t \t .pipe(新tar.Parse()) \t \t。對( '項目',函數(入口) \t \t \t { \t \t \t \t { \t \t \t \t \t變種ISDIR = '指南' === entry.type; \t \t \t \t \t var fullpath = path.join(dest,entry.path); \t \t \t \t \t var directory = isDir? fullpath:path.dirname(fullpath); \t \t \t \t \t mkdirp(目錄,函數(ERR){ \t \t \t \t \t如果(ERR)拋出犯錯; \t \t \t \t \t如果(ISDIR) \t \t \t \t \t { \t \t \t! \t \t \t entry.pipe(fs.createWriteStream(fullpath) \t \t \t \t \t \t。on('error',function(e){alert('Error');}) ); \t \t \t \t \t}});} \t \t \t})上( '關閉',函數(){的setTimeout(readXMLFile(sysObject.path + '\\ layout_new.xml'),0);}) –