我有一个文件,该文件以JSON形式存储许多JavaScript对象,我需要读取该文件,创建每个对象并对其进行处理(以我为例将其插入到db中)。JavaScript对象可以表示为以下格式:
格式A:
[{name: 'thing1'},
....
{name: 'thing999999999'}]
或 格式B:
{name: 'thing1'} // <== My choice.
...
{name: 'thing999999999'}
请注意,...
表示很多JSON对象。我知道我可以将整个文件读入内存,然后JSON.parse()
像这样使用:
fs.readFile(filePath, 'utf-8', function (err, fileContents) {
if (err) throw err;
console.log(JSON.parse(fileContents));
});
但是,该文件可能确实很大,我更喜欢使用流来完成此操作。我在流中看到的问题是,文件内容随时可能被分解成数据块,那么如何JSON.parse()
在此类对象上使用?
理想情况下,每个对象将被读取为一个单独的数据块,但是我不确定 如何做到这一点 。
var importStream = fs.createReadStream(filePath, {flags: 'r', encoding: 'utf-8'});
importStream.on('data', function(chunk) {
var pleaseBeAJSObject = JSON.parse(chunk);
// insert pleaseBeAJSObject in a database
});
importStream.on('end', function(item) {
console.log("Woot, imported objects into the database!");
});*/
注意,我希望防止将整个文件读入内存。时间效率对我来说并不重要。是的,我可以尝试一次读取多个对象并一次插入所有对象,但这是性能上的调整-
我需要一种方法,确保无论文件中包含多少个对象,都不会导致内存过载。
我可以选择使用,FormatA
或者选择FormatB
其他方式,只需在您的答案中指定即可。谢谢!
要逐行处理文件,只需要将文件的读取与作用于该输入的代码分离开。您可以通过缓冲输入直到碰到换行符来完成此操作。假设每行有一个JSON对象(基本上是格式B):
var stream = fs.createReadStream(filePath, {flags: 'r', encoding: 'utf-8'});
var buf = '';
stream.on('data', function(d) {
buf += d.toString(); // when data is read, stash it in a string buffer
pump(); // then process the buffer
});
function pump() {
var pos;
while ((pos = buf.indexOf('\n')) >= 0) { // keep going while there's a newline somewhere in the buffer
if (pos == 0) { // if there's more than one newline in a row, the buffer will now start with a newline
buf = buf.slice(1); // discard it
continue; // so that the next iteration will start with data
}
processLine(buf.slice(0,pos)); // hand off the line
buf = buf.slice(pos+1); // and slice the processed data off the buffer
}
}
function processLine(line) { // here's where we do something with a line
if (line[line.length-1] == '\r') line=line.substr(0,line.length-1); // discard CR (0x0D)
if (line.length > 0) { // ignore empty lines
var obj = JSON.parse(line); // parse the JSON
console.log(obj); // do something with the data here!
}
}
每次文件流从文件系统接收数据时,它都会存储在缓冲区中,然后pump
被调用。
如果缓冲区中没有换行符,pump
则不执行任何操作即可返回。下次流获取数据时,会将更多数据(可能还有换行符)添加到缓冲区中,然后我们将拥有一个完整的对象。
如果有换行符,请pump
从开始处将缓冲区切到换行符,然后将其移交给process
。然后,它再次检查缓冲区中是否还有换行符(while
循环)。这样,我们可以处理在当前块中读取的所有行。
最后,process
每条输入线被调用一次。如果存在,它将去除回车符(以避免出现行尾问题– LF vs
CRLF),然后将JSON.parse
其中之一称为行。此时,您可以对对象执行任何所需的操作。
注意,JSON.parse
它接受什么作为输入是严格的。您必须 用双引号 将标识符和字符串值引起 来
。换句话说,{name:'thing1'}
会抛出错误;您必须使用{"name":"thing1"}
。
因为一次最多只能有一块数据存储在内存中,所以这将极大地提高存储效率。这也将非常快。快速测试显示,我在15毫秒内处理了10,000行。
问题内容: 我正在研究可访问API的cron脚本,可接收JSON文件(大量对象)并将其存储在本地。完成后,另一个脚本需要解析下载的JSON文件,并将每个对象插入MySQL数据库。 我目前正在使用和。这将尝试在尝试处理之前将整个文件读入内存。除了我的JSON文件通常在250MB-1GB +之间的事实之外,这将很好。我知道我可以增加我的PHP内存限制,但这在我看来似乎并不是最大的答案。我知道我可以运行
问题内容: 我正在创建一个Android应用程序,该应用程序应将Json从文件或URL解析为jsonarray和jsonobjects。问题是我的json是3.3 mb,当我使用一个简单的代码时,是这样的:(现在无法访问我的真实代码,因为我正在工作,从教程中复制了一些代码;因此其中可能有一些错误) (假设我已经有我的输入流内容) 当我在Android设备上运行此代码时,将字符串解析为jsonArr
我正在创建一个android应用程序,它应该解析一个Json从一个文件或url到一个json数组和json对象。问题是我的json是3.3mb,当我使用一个简单的代码时,就像这样:(不能访问我的真实代码,因为我在工作,从教程中复制了一些代码;所以可能会有一些错误) (假设我已经有了inputstream内容) 当我在android设备上运行这段代码时,在将字符串解析为jsonArray时,会出现O
我有一个文件,它以JSON形式存储了许多JavaScript对象,我需要读取该文件,创建每个对象,并对它们做一些事情(在我的例子中,将它们插入数据库)。JavaScript对象可以用一种格式表示: 格式A: 或格式B: 请注意,
问题内容: 我有以下问题: 我有一个XML文件(大约1GB),并且必须上下迭代(即不连续;一个接一个),以便获取所需的数据并对其进行一些操作。最初,我使用了DOM Java包,但是很显然,在解析XML文件时,JVM达到了其最大堆空间并停止了运行。 为了解决这个问题,我想到的解决方案之一是找到另一个解析器,该解析器迭代XML中的每个元素,然后将其内容存储在硬盘上的临时SQLite数据库中。因此,通过
我使用axios从API获取数据,然后使用节点中的数据。js应用程序。数据是由300个对象组成的数组,如下所示: 获取此对象数组后,我需要转换每个对象:用新的键替换其键,并将一些值转换为适当的数据类型(字符串到浮点): 现在我只使用For循环,并在每次迭代中转换每个对象的键和值。但是像这样的物体将会有成千上万。它将是处理这些数据的工人。在节点中处理它们的最佳方式是什么。js? 我将使用一些现成的队