2013-11-23 16 views
1

我想要做什麼應該看起來很簡單:採用文件名爲X的文件,並創建一個gzipped版本爲「X.gz」。的NodeJS的zlib的模塊不拿出一個方便zlib.gzip(INFILE,OUTFILE),所以我想我會用的輸入流,輸出流和zlib的但gzipper,然後通過管道它們:gzipping與nodejs流文件導致內存泄漏

var zlib = require("zlib"), 
    zipper = zlib.createGzip(), 
    fs = require("fs"); 

var tryThing = function(logfile) { 
    var input = fs.createReadStream(logfile, {autoClose: true}), 
     output = fs.createWriteStream(logfile + ".gz"); 

    input.pipe(zipper).pipe(output); 

    output.on("end", function() { 
    // delete original file, it is no longer needed 
    fs.unlink(logfile); 

    // clear listeners 
    zipper.removeAllListeners(); 
    input.removeAllListeners(); 
    }); 
} 

然而, ,每次運行這個函數時,Node.js的內存佔用量增長了大約100kb。我忘了告訴溪流他們應該再次自殺,因爲它們不再需要了嗎?

或者,有沒有辦法只是gzip文件而不打擾流和管道?我試着用google搜索「node.js gzip文件」,但它只是指向API文檔的鏈接,以及關於gzipping流和緩衝區的堆棧溢出問題,而不是如何只是gzip文件。

回答

2

我覺得你需要正確的unpipeclose這個流。只需removeAllListeners()可能不足以清理乾淨。由於流可能正在等待更多數據(並因此不必要地在內存中保持活躍狀態​​)。

另外,您還沒有關閉輸出流,而且我會聽輸入流的end而不是輸出。

// cleanup 
input.once('end', function() { 
    zipper.removeAllListeners(); 
    zipper.close(); 
    zipper = null; 
    input.removeAllListeners(); 
    input.close(); 
    input = null; 
    output.removeAllListeners(); 
    output.close(); 
    output = null; 
}); 

此外,我不認爲從zlib.createGzip()返回的流可以共享結束一次。你應該在tryThing每次迭代創建一個新:

var input = fs.createReadStream(logfile, {autoClose: true}), 
    output = fs.createWriteStream(logfile + ".gz") 
    zipper = zlib.createGzip(); 

input.pipe(zipper).pipe(output); 

沒有帶測試此壽,因爲我沒有記憶曲線工具附近現在。

+0

好點,但如果調用close(),removealllisteneres和null賦值就不再需要了。我最終選擇了直接in.pipe(out)並重新指定每個週期,然後使用less pipe -y readfile/gzip/writefile/unlink來對最終完成的文件進行gzip壓縮,但仍得到滿意答案。 –