1

オブジェクトごとに JSON の配列をストリーミングしようとしていますが、生の JSON 文字列としてインポートする必要があります。

次のような入力の配列が与えられた場合:

[
 {"object":1},
 {"object":2},
 ...
 {"object":n}
]

私は文字列を反復しようとしています:

{"object":1}
{"object":2}
...
{"object":n}

ストリーミング API を使用して構造をナビゲートし、オブジェクトに遭遇したことなどを検証できますが、String を取得する方法は理想的だと思います。

現在:

//[...]
//we have read a START_OBJECT token
JsonNode node = parser.readValueAsTree();
String jsonString = anObjectMapper.writeValueAsString(node);
//as opposed to  String jsonString = node.toString() ;
//[...]

JsonNode 構造全体の構築には大量のオーバーヘッドが伴うと思いますが、再シリアル化だけでは意味がないので、より良い解決策を探しています。これに沿った何かが理想的です:

//[...]
//we have read a START_OBJECT token
String jsonString = parser.readValueAsString()
//or parser.skipChildrenAsString()
//[...]

オブジェクトは明らかに単純ではありません

{"object":1}

そのため、無意味なノード構築に時間を無駄にしないようにしています。コンテンツをオブジェクトにマッピングしてそれを操作するなど、理想的な方法があるかもしれませんが、私はそれができる立場にありません。既存のコードを操作するには、一度に 1 つのオブジェクトで生の JSON 文字列が必要です。

提案やコメントをお待ちしております。ありがとう!

EDIT : parser.getText() は、現在のトークンをテキストとして返します (例: START_OBJECT -> "{") が、オブジェクトの残りの部分は返しません。

Edit2 :ストリーミング API を使用する動機は、オブジェクトを 1 つずつバッファリングすることです。実際の json ファイルは非常に大きくなる可能性があり、各オブジェクトは使用後に破棄される可能性があるため、単純に反復する必要があります。

4

1 に答える 1

4

JSON のトークン化を回避する方法はありません (そうしないと、パーサーはオブジェクトの開始位置と終了位置を認識できません)、常に何らかのレベルの解析と生成が必要になります。

ただし、値を次のように読み取ることで、オーバーヘッドをわずかに減らすことができます。TokenBufferこれは、メモリ/パフォーマンスのオーバーヘッドが最も低いジャクソンの内部型です (そして、バッファリングが必要な場合は常に内部的に使用されます)。

TokenBuffer buf = parser.readValueAs(TokenBuffer.class);
// write straight from buffer if you have JsonGenerator
jgen.writeObject(buf);
// or, if you must, convert to byte[] or String
byte[] stuff = mapper.writeValueAsBytes();

ただし、もう少しうまくやることができますJsonGenerator。出力用に作成できる場合は、次を使用してJsonGenerator.copyCurrentStructure(JsonParser);ください。

jgen.copyCurrentStructure(jp); // points to END_OBJECT after copy

これにより、すべてのオブジェクト割り当てが回避されます。JSON をデコードし、JSON としてエンコードする必要がありますが、かなり効率的です。実際、JSON の読み取り、XML/Smile/CSV/YAML/Avro の書き込みなど、Jackson がサポートする任意のフォーマット間でのトランスコーディングにもこれを使用できます。

于 2013-08-05T22:32:42.843 に答える