我正在尝试使用Jackson SAX解析器实现JSON数组迭代器(请不要问为什么)。 我的应用程序应该使用大量文件(最多5 MiB),这是一个问题。
这就是我初始化JsonParser并调用迭代器创建的方法。 我创建了使用放在\ raw文件夹中的JSON初始化的InputStream。
private JsonArrayIterator getIterator(String needle) throws IOException { InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.products); inputStream.mark(-1); try { JsonParser jsonParser = createJsonParser(inputStream); // Some unrelated code return new JsonArrayIterator(jsonParser); } catch (IOException e) { e.printStackTrace(); } finally { inputStream.close(); } return null; }
这是我的迭代器类。
private Object parseNextObject() throws IOException { // I'm not using ObjectMapper because of reasons HashMap nextObject = new HashMap(); int objectsCount = 1; while (objectsCount > 0) { JsonToken currentToken = currentParser.nextValue(); if(currentToken == JsonToken.START_OBJECT) { ++objectsCount; } else if(currentToken == JsonToken.END_OBJECT) { --objectsCount; } else if(currentToken == JsonToken.START_ARRAY) { String currentName = currentParser.getCurrentName(); ArrayList list = new ArrayList(100); JsonArrayIterator it = new JsonArrayIterator(currentParser); while (it.hasNext()) { list.add(it.next()); } nextObject.put(currentName, list); } else { // Here exception is throwed nextObject.put(currentParser.getCurrentName(), currentParser.getText()); } } currentParser.nextToken(); // Skip END_OBJECT return nextObject; }
它似乎工作正常...... OH,等待。
我在一些巨大的文件中有3个部分(命名数组)。 它首先成功解析(一个很小的,1000字节以下)。但我接下来无法解析。
Next数组包含带有简单对象的嵌套数组(如下所示):
{ "properties":[ { "id":"1", "title":"\u0426\u0432\u0435\u0442", "values":[ { "id":"1_2", "title":"\u0427\u0435\u0440\u043d\u044b\u0439" }, { "id":"1_5005", "title":"\u0417\u0435\u043b\u0435\u043d\u044b\u0439" }, { "id":"1_5006", "title":"\u0421\u0435\u0440\u044b\u0439" } ] } ] }
对于值中的一个对象,我调用nextObject.put。 currentParser.getCurrentName()成功运行并返回正确的字符串,但currentParser.getText()失败。这不是JSON问题:它完美地映射到iOS上。它不是对象或迭代器创建问题:我可以删除解析器抛出异常的地方,但它会在同一个地方失败。
这是堆栈跟踪:
05-15 21:57:28.617: ERROR/AndroidRuntime(14758): FATAL EXCEPTION: main java.lang.NullPointerException: asset at android.content.res.AssetManager.readAsset(Native Method) at android.content.res.AssetManager.access$700(AssetManager.java:36) at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:576) at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.loadMore(UTF8StreamJsonParser.java:174) at com.fasterxml.jackson.core.base.ParserBase.loadMoreGuaranteed(ParserBase.java:425) at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:1930) at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:1911) at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:276) at ru.studiomobile.JsonArrayIterator.parseNextObject(JsonArrayIterator.java:57) at ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73) at ru.studiomobile.JsonArrayIterator.parseNextObject(JsonArrayIterator.java:47) at ru.studiomobile.JsonArrayIterator.next(JsonArrayIterator.java:73) at ru.studiomobile.MainActivity$2.onClick(MainActivity.java:81) at android.view.View.performClick(View.java:3127) at android.view.View$PerformClick.run(View.java:12025) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:132) at android.app.ActivityThread.main(ActivityThread.java:4126) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:491) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) at dalvik.system.NativeStart.main(Native Method)
我注意到有一种叫做Utf8StreamJsonParser的东西。它有一个名为_inputEnd的字段等于4000(为什么是4000?)。当其他字段_inputPtr变大时会抛出异常。我该如何处理?我尝试使用带有预定义块大小的BufferedInputStream而不是InputStream,但它没有效果。
有关某些行的信息
47: list.add(it.next()); 73: return parseNextObject(); 75: e.printStackTrace();
没什么特别的。
答案 0 :(得分:3)
这是一个明显的问题:我忘记了在创建解析器后关闭流...