我正在尝试使用 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();
没什么特别的。