我有一个大的json文件,它是换行符分隔的JSON,其中多个标准JSON对象由额外的换行符分隔,例如。
{'name':'1','age':5}
{'name':'2','age':3}
{'name':'3','age':6}
我现在在node.js中使用JSONStream来解析一个大的json文件,我使用JSONStream的原因是因为它基于流。
但是,示例中的两个解析语法都无法帮助我在每行中用分离的JSON解析这个json文件
var parser = JSONStream.parse(**['rows', true]**);
var parser = JSONStream.parse([**/./**]);
有人可以帮助我吗
答案 0 :(得分:16)
警告:由于编写了这个答案,JSONStream库removed the emit root event functionality的作者显然是为了修复内存泄漏。 如果您需要emit root功能,可以使用0.x.x版本。
以下是未经修改的原始答案:
来自readme:
JSONStream.parse(路径)
path
应该是属性名称,RegExps,布尔值和/或函数的数组。与路径匹配的任何对象都将作为'data'
发出。收到所有数据后会发出
'root'
个事件。'root'
事件传递根对象&匹配对象的数量。
在您的情况下,由于您想要取回JSON对象而不是特定属性,因此您将使用'root'
事件,而不需要指定路径。
您的代码可能如下所示:
var fs = require('fs'),
JSONStream = require('JSONStream');
var stream = fs.createReadStream('data.json', {encoding: 'utf8'}),
parser = JSONStream.parse();
stream.pipe(parser);
parser.on('root', function (obj) {
console.log(obj); // whatever you will do with each JSON object
});
答案 1 :(得分:1)
JSONstream用于解析单个巨大的JSON对象,而不是很多JSON对象。您希望在换行符处拆分流,然后将它们解析为JSON。
NPM包split声称要进行此拆分,甚至为您提供feature to parse the JSON lines。
答案 2 :(得分:0)
如果文件不够大,这是一个简单但不高效的解决方案:
titel
答案 3 :(得分:0)
我创建了一个程序包@jsonlines/core
,该程序包将jsonlines解析为对象流。
您可以尝试以下代码:
npm install @jsonlines/core
const fs = require("fs");
const { parse } = require("@jsonlines/core");
// create a duplex stream which parse input as lines of json
const parseStream = parse();
// read from the file and pipe into the parseStream
fs.createReadStream(yourLargeJsonLinesFilePath).pipe(parseStream);
// consume the parsed objects by listening to data event
parseStream.on("data", (value) => {
console.log(value);
});
请注意,parseStream
是标准节点双工流。
因此,您还可以使用for await ... of
或其他方式使用它。
答案 4 :(得分:0)
当文件小到可以放入内存时,这是另一种解决方案。它一次性读取整个文件,通过在换行符处拆分(去除末尾的空行)将其转换为数组,然后解析每一行。
import fs from "fs";
const parsed = fs
.readFileSync(`data.jsonl`, `utf8`)
.split(`\n`)
.slice(0, -1)
.map(JSON.parse)