我有一个适用于Android应用程序的项目,该项目可以下载庞大的Json String并提取程序所需的有用信息。但是该文件确实很大(将近100mb)才能存储到内存中,所以我需要读取它的较小部分。
我所看到的Json字符串和所有字符串都是一行。因此,由于OOM(内存不足),我无法逐行读取
{"Tag":"[{\"mySubTag\":\"myValue\/myValue\"},{\"mySubTag\":\"myValueWithAnotherEscapedStringInside\\xyz\/likeThis\"},...]"}
通常,我使用来自JsonObject的标签作为字符串提取它们,然后从“ Tag”属性获取字符串值,然后再次使用此字符串创建新的JsonArray,以便从JsonArray类自动取消转义,但Android不允许放置Json文件(或String)进入内存。我试图通过流删除反斜杠,但如果subTag值内部包含转义字符,则它不是正确的unescape方法。
我的问题是什么是完成这项工作的最佳方式和性能友好的方式?
(注意:对不起,英语不好)
更新1:
在@pskink重新命令后,我使用了android.util.JsonReader,并且编写了如下代码:
JsonReader jsonReader = new JsonReader(new FileReader(f));//f is defined previous code but not shown!
jsonReader.beginObject();
String name = jsonReader.nextName();
String value = jsonReader.nextString();
Log.d(AppConstants.TAG, "name: " + name);
Log.d(AppConstants.TAG, "value: " + value.length());//value is so big I only care about its length
JsonReader jsonReader1 = new JsonReader(new StringReader(value));
while (jsonReader1.hasNext()) {
JsonToken token = jsonReader1.peek();
switch (token) {
case BEGIN_ARRAY:
jsonReader1.beginArray();
Log.d(AppConstants.TAG, "BEGIN_ARRAY");
continue;
case END_ARRAY:
jsonReader1.endArray();
Log.d(AppConstants.TAG, "END_ARRAY");
continue;
case BEGIN_OBJECT:
jsonReader1.beginObject();
Log.d(AppConstants.TAG, "BEGIN_OBJECT");
continue;
case END_OBJECT:
jsonReader1.endObject();
Log.d(AppConstants.TAG, "END_OBJECT");
continue;
case NAME:
Log.d(AppConstants.TAG, "name: " + jsonReader1.nextName());
continue;
case STRING:
Log.d(AppConstants.TAG, "String: " + jsonReader1.nextString());
continue;
case NUMBER:
Log.d(AppConstants.TAG, "number: " + jsonReader1.nextString());
continue;
case BOOLEAN:
Log.d(AppConstants.TAG, "boolean: " + jsonReader1.nextBoolean());
continue;
case NULL:
jsonReader1.nextNull();
continue;
case END_DOCUMENT:
Log.d(AppConstants.TAG, "END_DOCUMENT");
break;
}
}
我的输出是:
Tag
69387276
BEGIN_ARRAY
BEGIN_OBJECT
name: mySubTag
String: myValue/myValue
我很困惑为什么其余数组元素被忽略了!
更新2:
经过一些调试过程,我意识到 hasNext()方法返回“如果 current 数组或对象具有另一个元素,则返回true”。但是当前不是后来的元素,所以我像这样更新了while循环:
while (jsonReader1.peek()!=JsonToken.END_DOCUMENT) {
JsonToken token = jsonReader1.peek();
switch(token){
...
}
}
答案 0 :(得分:1)
@pskink建议android.util.JsonReader
使用此库编写代码后解决了我的问题。要查看我的代码,请查看有问题的更新。
感谢@pskink。