我正在尝试使用 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; }
它似乎工作得很好......哦,等等。
我在一些大文件中有 3 个部分(命名数组)。 它首先成功解析(一个很小的,不到 1000 字节)。但是接下来我无法解析。
下一个数组有带有简单对象的嵌套数组(像这样):
{ "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 变大时,它会抛出异常。我该如何处理?我尝试使用具有预定义 block 大小的 BufferedInputStream 而不是 InputStream,但它没有效果。
更新
一些线路的信息
47: list.add(it.next()); 73: return parseNextObject(); 75: e.printStackTrace();
没什么特别的。
最佳答案
这是一个明显的问题:我忘记在创建解析器后关闭流...
关于java - Jackson SAX 解析器在解析巨大的 JSON 时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10612006/