26

我有一个大的 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([**/./**]);

有人可以帮我吗

4

5 回答 5

20

警告:由于编写了此答案,因此 JSONStream 库的作者删除了发出根事件功能,显然是为了修复内存泄漏。这个库的未来用户,如果你需要发出根功能,你可以使用 0.xx 版本。

以下是未经修改的原始答案

自述文件

JSONStream.parse(路径)

path应该是属性名称、正则表达式、布尔值和/或函数的数组。任何与路径匹配的对象都将作为'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
});
于 2013-02-28T00:57:08.333 回答
4

JSONstream 旨在解析单个巨大的 JSON 对象,而不是很多 JSON 对象。您想在换行符处拆分流,然后将它们解析为 JSON。

NPM 包split声称可以进行这种拆分,甚至具有为您解析 JSON 行的功能。

于 2017-12-11T10:36:07.250 回答
1

如果您的文件不够大,这是一个简单但不高效的解决方案:

const fs = require('fs');

let rawdata = fs.readFileSync('fileName.json');

let convertedData = String(rawdata)
    .replace(/\n/gi, ',')
    .slice(0, -1);

let JsonData= JSON.parse(`[${convertedData}]`); 
于 2020-05-04T08:40:10.763 回答
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或其他方式来消费它。

于 2020-08-15T18:45:33.840 回答
0

当文件足够小以适合内存时,这是另一种解决方案。它一次性读取整个文件,通过在换行符处拆分它(删除末尾的空白行)将其转换为数组,然后解析每一行。

import fs from "fs";

const parsed = fs
  .readFileSync(`data.jsonl`, `utf8`)
  .split(`\n`)
  .slice(0, -1)
  .map(JSON.parse)
于 2021-07-21T18:31:52.753 回答