Jackson SAX パーサーを使用して JSON 配列反復子を実装しようとしています (理由は聞かないでください)。私のアプリは巨大なファイル (最大 5 MiB) で動作するはずですが、それが問題です。
これが、JsonParser を初期化し、イテレータの作成を呼び出す方法です。\raw フォルダに置かれた JSON で初期化された InputStream を作成します。
プライベート JsonArrayIterator getIterator(String needle) が IOException をスローする
{
InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.products);
inputStream.mark(-1);
試す {
JsonParser jsonParser = createJsonParser(inputStream);
// 関連のないコード
新しい JsonArrayIterator(jsonParser) を返します。
} キャッチ (IOException e) {
e.printStackTrace();
} 最後に {
inputStream.close();
}
null を返します。
}
そして、これが私のイテレータクラスです。
private Object parseNextObject() は IOException をスローします {
// 理由により ObjectMapper を使用していません
HashMap nextObject = new HashMap();
int オブジェクト数 = 1;
while (objectsCount > 0) {
JsonToken currentToken = currentParser.nextValue();
if(currentToken == JsonToken.START_OBJECT) {
++objectsCount;
}
else if(currentToken == JsonToken.END_OBJECT) {
--objectsCount;
}
それ以外の場合 (currentToken == JsonToken.START_ARRAY) {
String currentName = currentParser.getCurrentName();
ArrayList リスト = 新しい ArrayList(100);
JsonArrayIterator it = new JsonArrayIterator(currentParser);
while (it.hasNext()) {
list.add(それ.next());
}
nextObject.put(現在の名前、リスト);
}
そうしないと {
// ここで例外がスローされます
nextObject.put(currentParser.getCurrentName(), currentParser.getText());
}
}
currentParser.nextToken(); // END_OBJECT をスキップ
次のオブジェクトを返します。
}
完璧に動作するようです...ああ、待ってください。
巨大なファイルに 3 つのセクション (名前付き配列) があります。最初に正常に解析されます (1000 バイト未満の小さなもの)。しかし、次は解析できません。
次の配列には、単純なオブジェクトを含むネストされた配列があります (このように):
{
"プロパティ":[
{
"id":"1",
"タイトル":"\u0426\u0432\u0435\u0442",
"値":[
{
"id":"1_2",
"タイトル":"\u0427\u0435\u0440\u043d\u044b\u0439"
}、
{
"id":"1_5005",
"タイトル":"\u0417\u0435\u043b\u0435\u043d\u044b\u0439"
}、
{
"id":"1_5006",
"タイトル":"\u0421\u0435\u0440\u044b\u0439"
}
]
}
]
}
値の 1 つのオブジェクトに対して、nextObject.put を呼び出します。currentParser.getCurrentName() は正常に実行され、正しい文字列が返されますが、currentParser.getText() は失敗します。これは JSON の問題ではありません。iOS では完全にマッピングされています。オブジェクトやイテレータの作成の問題ではありません。パーサーが例外をスローする場所を削除できますが、同じ場所で失敗します。
スタック トレースは次のとおりです。
05-15 21:57:28.617: エラー/AndroidRuntime(14758): 致命的な例外: メイン
java.lang.NullPointerException: 資産
android.content.res.AssetManager.readAsset(ネイティブメソッド)で
android.content.res.AssetManager.access$700(AssetManager.java:36)
android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:576) で
com.fasterxml.jackson.core.json.UTF8StreamJsonParser.loadMore(UTF8StreamJsonParser.java:174)で
com.fasterxml.jackson.core.base.ParserBase.loadMoreGuaranteed (ParserBase.java:425) で
com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2 (UTF8StreamJsonParser.java:1930) で
com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString (UTF8StreamJsonParser.java:1911) で
com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText (UTF8StreamJsonParser.java:276) で
ru.studiomobile.JsonArrayIterator.parseNextObject (JsonArrayIterator.java:57) で
ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73) で
ru.studiomobile.JsonArrayIterator.parseNextObject (JsonArrayIterator.java:47) で
ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73) で
ru.studiomobile.MainActivity$2.onClick(MainActivity.java:81)で
android.view.View.performClick(View.java:3127) で
android.view.View$PerformClick.run(View.java:12025) で
android.os.Handler.handleCallback(Handler.java:587) で
android.os.Handler.dispatchMessage(Handler.java:92) で
android.os.Looper.loop(Looper.java:132)で
android.app.ActivityThread.main(ActivityThread.java:4126) で
java.lang.reflect.Method.invokeNative(ネイティブ メソッド) で
java.lang.reflect.Method.invoke(Method.java:491) で
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) で
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:602) で
dalvik.system.NativeStart.main (ネイティブ メソッド) で
Utf8StreamJsonParser というものがあることに気付きました。4000 に等しい _inputEnd という名前のフィールドがあります (なぜ 4000 なのですか?)。他のフィールド _inputPtr が大きくなると、例外がスローされます。どうすれば対処できますか?InputStream の代わりに定義済みのブロック サイズで BufferedInputStream を使用しようとしましたが、効果がありませんでした。
アップデート
いくつかの行についての情報
47: list.add(それ.next());
73: return parseNextObject();
75: e.printStackTrace();
特にない。