[英]Running out of memory writing to a file in NodeJS
我正在處理大量我正在操作並將其存儲在文件中的數據。 我遍歷數據集,然后我想將它全部存儲在JSON文件中。
我的初始方法使用fs,將它全部存儲在一個對象然后轉儲它不起作用,因為我的內存耗盡,它變得非常慢。
我現在正在使用fs.createWriteStream,但據我所知,它仍然將它全部存儲在內存中。
我希望將數據逐個對象地寫入文件,除非有人可以推薦更好的方法。
我的部分代碼:
// Top of the file
var wstream = fs.createWriteStream('mydata.json');
...
// In a loop
let JSONtoWrite = {}
JSONtoWrite[entry.word] = wordData
wstream.write(JSON.stringify(JSONtoWrite))
...
// Outside my loop (when memory is probably maxed out)
wstream.end()
我想我正在使用Streams錯誤,有人可以告訴我如何將所有這些數據寫入文件而不會耗盡內存嗎? 我在網上找到的每個例子都與讀取流有關,但由於我正在對數據進行計算,我不能使用可讀流。 我需要按順序添加到此文件。
問題是你不是在等待將數據刷新到文件系統,而是在緊密循環中同步地將新數據和新數據同時發送到流中。
這是一個適合你的偽代碼:
// Top of the file
const wstream = fs.createWriteStream('mydata.json');
// I'm no sure how're you getting the data, let's say you have it all in an object
const entry = {};
const words = Object.keys(entry);
function writeCB(index) {
if (index >= words.length) {
wstream.end()
return;
}
const JSONtoWrite = {};
JSONtoWrite[words[index]] = entry[words[index]];
wstream.write(JSON.stringify(JSONtoWrite), writeCB.bind(index + 1));
}
wstream.write(JSON.stringify(JSONtoWrite), writeCB.bind(0));
您也應該將數據源包裝在可讀的流中。 我不知道你的來源是什么,但你必須確保它不會將所有數據加載到內存中。
例如,假設您的數據集來自另一個文件,其中JSON對象使用行尾字符進行拆分,您可以創建一個讀取流,如下所示:
const Readable = require('stream').Readable;
class JSONReader extends Readable {
constructor(options={}){
super(options);
this._source=options.source: // the source stream
this._buffer='';
source.on('readable', function() {
this.read();
}.bind(this));//read whenever the source is ready
}
_read(size){
var chunk;
var line;
var lineIndex;
var result;
if (this._buffer.length === 0) {
chunk = this._source.read(); // read more from source when buffer is empty
this._buffer += chunk;
}
lineIndex = this._buffer.indexOf('\n'); // find end of line
if (lineIndex !== -1) { //we have a end of line and therefore a new object
line = this._buffer.slice(0, lineIndex); // get the character related to the object
if (line) {
result = JSON.parse(line);
this._buffer = this._buffer.slice(lineIndex + 1);
this.push(JSON.stringify(line) // push to the internal read queue
} else {
this._buffer.slice(1)
}
}
}}
現在你可以使用了
const source = fs.createReadStream('mySourceFile');
const reader = new JSONReader({source});
const target = fs.createWriteStream('myTargetFile');
reader.pipe(target);
然后你會有更好的記憶流量:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.