我正在处理我正在操作并将其存储在文件中的大量数据。我遍历数据集,然后我想将它全部存储在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错误,有人可以告诉我如何将所有这些数据写入文件而不会耗尽内存吗?我在网上找到的每个例子都与读取流有关,但由于我正在对数据进行计算,我不能使用可读流。我需要按顺序添加到此文件中。
答案 0 :(得分:0)
问题在于您不是在等待将数据刷新到文件系统,而是在紧密循环中同步地将新数据和新数据同时发送到流中。
这是一段适用于您的伪代码:
// 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));
答案 1 :(得分: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);
然后你会有更好的记忆力流:
请注意,图片和上面的示例均来自优秀的nodejs in practice book