メモリに制約のある環境で大規模な JSON ストリームを処理する Json.NET
メモリに制約のある環境では、類似したオブジェクトを多数含む JSON ファイルを解析するのは困難です。次のシナリオを考えてみましょう:
巨大な JSON ファイルには、同じ構造を持つ多数の JSON オブジェクトが含まれています。各オブジェクトが個別のファイルである場合は、オブジェクトを 1 つずつ逆シリアル化できます。ただし、データのネストされた性質により、これらのオブジェクトの JSON 配列を直接逆シリアル化すると、リストではなくオブジェクトが予期されていたという例外がスローされます。
JSON ファイル全体を C# オブジェクトのリストに逆シリアル化しようとすると、JSON ファイル全体を RAM に読み取る問題が回避されます。ただし、JSON ファイルのすべてのデータをメモリ内に保持したままの C# リスト オブジェクトを作成するという新たな問題が発生します。
これらの制限を克服するには、オブジェクトを一度に 1 つずつ読み取る戦略が必要です。このアプローチにより、JSON 文字列全体またはすべてのデータを C# オブジェクトとして RAM にロードする必要がなくなります。
解決策
次のコード例は、このアプローチを示しています。
<code class="language-csharp">JsonSerializer serializer = new JsonSerializer(); MyObject o; using (FileStream s = File.Open("bigfile.json", FileMode.Open)) using (StreamReader sr = new StreamReader(s)) using (JsonReader reader = new JsonTextReader(sr)) { while (reader.Read()) { // 只在流中存在"{"字符时才反序列化 if (reader.TokenType == JsonToken.StartObject) { o = serializer.Deserialize<MyObject>(reader); // 对o进行处理 } } }</code>
このコードは、ループ内でオブジェクトを逆シリアル化する最初のメソッドをシミュレートしますが、リーダーがストリーム内で「{」文字を検出した場合にのみオブジェクトを逆シリアル化します。このアプローチでは、別の開始オブジェクト マーカーが見つかるまで次のオブジェクトにスキップすることで、RAM を過剰に使用することなく JSON ストリームを効率的に処理します。 なお、コード中のmyobject
をMyObject
に修正し、実際の状況に応じて後続の操作を追加しやすいようにo
オブジェクトの処理に関するコメントを追加しました。
以上がJson.NET の限られた RAM で大規模な JSON ストリームを効率的に解析するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。