Как проанализировать большой файл JSON, разделенный символом Newline, с помощью модуля JSONStream в node.js?

У меня есть большой файл JSON, это JSON, разделенный символом Newline, где несколько стандартных объектов JSON ограничены дополнительными символами новой строки, например

{'name':'1','age':5}
{'name':'2','age':3}
{'name':'3','age':6}

Сейчас я использую JSONStream в node.js для анализа большого файла json, поэтому я использую JSONStream, потому что он основан на потоке.

Однако оба синтаксиса синтаксического анализа в примере не могут помочь мне проанализировать этот файл json с разделенным JSON в каждой строке.

var parser = JSONStream.parse(**['rows', true]**);
var parser = JSONStream.parse([**/./**]);

Может ли кто-нибудь помочь мне с этим

5 ответов

Решение

Предупреждение: поскольку этот ответ был написан, автор библиотеки JSONStream удалил функциональность события emit root, очевидно, для устранения утечки памяти. Будущие пользователи этой библиотеки, вы можете использовать версии 0.xx, если вам нужна функциональность emit root.

Ниже приведен неизмененный оригинальный ответ:

Из 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
});

JSONstream предназначен для анализа одного огромного объекта JSON, а не множества объектов JSON. Вы хотите разделить поток на новые строки, а затем проанализировать их как JSON.

Разделение пакета NPM утверждает, что делает это разделение, и даже имеет функцию для анализа строк JSON для вас.

Если ваш файл недостаточно велик, вот простое, но неэффективное решение:

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}]`); 

Я создал пакет @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 или другие способы его употребления.

      import fs from "fs";

const parsed = fs
  .readFileSync(`data.jsonl`, `utf8`)
  .split(`\n`)
  .slice(0, -1)
  .map(JSON.parse)
Другие вопросы по тегам