我正在尝试使用 Jackson SAX 解析器实现 JSON 数组迭代器(请不要问为什么)。我的应用程序应该可以处理大文件(最多 5 MiB),这是个问题。
这就是我初始化 JsonParser 并调用迭代器创建的方式。我创建了 InputStream,并使用放置在 \raw 文件夹中的 JSON 进行了初始化。
私有 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(); } 返回空值; }
这是我的迭代器类。
私有对象 parseNextObject() 抛出 IOException { // 由于某些原因,我没有使用 ObjectMapper HashMap nextObject = new HashMap(); int objectsCount = 1; 而(对象计数> 0){ JsonToken currentToken = currentParser.nextValue(); 如果(currentToken == JsonToken.START_OBJECT){ ++对象计数; } 否则如果(currentToken == JsonToken.END_OBJECT){ --对象计数; } 否则如果(currentToken == JsonToken.START_ARRAY){ 字符串 currentName = currentParser.getCurrentName(); ArrayList 列表 = 新的 ArrayList(100); JsonArrayIterator it = new JsonArrayIterator(currentParser); 而(it.hasNext()){ list.add(it.next()); } nextObject.put(currentName, list); } 别的 { // 这里抛出异常 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” } ] } ] }
对于值中的一个对象,我调用 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(Native Method) 在 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 的东西。它有一个名为 _inputEnd 的字段等于 4000(为什么是 4000?)。当其他字段 _inputPtr 变大时,它会引发异常。我该如何处理?我尝试使用具有预定义块大小的 BufferedInputStream 而不是 InputStream 但它没有效果。
更新
有关某些行的信息
47: 列表.add(it.next()); 73: 返回 parseNextObject(); 75: e.printStackTrace();
没什么特别的。