2013-11-14 58 views
3

變換一個文件,我想這樣做:流和與地方的NodeJS

var fs = require('fs'); 
var through = require('through'); 

var file = 'path/to/file.json'; 

var input = fs.createReadStream(file, 'utf8'); 
var output = fs.createWriteStream(file, 'utf8'); 

var buf = ''; 
input 
.pipe(through(function data(chunk) { buf += chunk; }, function end() { 
    var data = JSON.parse(buf); 
    // Do some transformation on the obj, and then... 
    this.queue(JSON.stringify(data, null, ' ')); 
}) 
.pipe(output); 

但這種失敗,因爲它試圖讀取和寫入到相同的目的地。有辦法繞過它,就像從上面的end回調中僅管道到output

有沒有更好的方法?更好的是,我的意思是使用更少的代碼或更少的內存。是的,我知道,我可能只是這樣做:

var fs = require('fs'); 
var file = 'path/to/file.json'; 

var str = fs.readFileSync(file, 'utf8'); 
var data = JSON.parse(str);  
// Do some transformation on the obj, and then... 
fs.writeFileSync(file, JSON.stringify(data, null, ' '), 'utf8'); 

回答

1

有你的代碼將使用內存,因爲你需要整個文件將其解析爲一個JavaScript對象沒有別的辦法。通過這種方式,您的代碼的兩個版本在內存方面都是等效的。如果你可以做一些工作而不必處理完整的JSON對象,請檢查JSONStream

在你的例子中,你應該應該讀取文件,然後解析並轉換它,然後將結果寫入文件;雖然你不應該使用的功能的同步版本,請參閱the end of this paragraph of the Node.js documentation

在忙碌的過程中,程序員強烈鼓勵使用這些調用的異步版本。同步版本將阻止整個過程,直到完成 - 停止所有連接。


無論如何,我不認爲你可以從文件中,當你覆蓋它讀取。同樣的問題見this particular answer

+0

儘管我同意避免使用同步版本,但在這個例子中,他們導致了快速和臨時構建步驟(而不是長時間運行的服務器進程)的代碼極少。感謝鏈接到bash的答案,這很有幫助! – Andrew

+0

確實。你能告訴我們輸入文件的內容和你想實現的轉換類型嗎?沒有這個,很難知道算法是否流式傳輸。 –

+0

內容是一個非常簡單的JSON文件,「{」key「:」value「,」someKeyToDelete「:{」yep「:」我不會在那裏「}}',我剛剛刪除'someKeyToDelete'它。 – Andrew