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();
特にない。