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バージョンを使用できます。

以下は、変更されていない元の回答です。

READMEから:

JSONStream.parse(path)

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
});
于 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/corejsonlinesをオブジェクトストリームとして解析するパッケージを作成しました。

次のコードを試すことができます。

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 に答える