场景
- 开发
JSON
应用时,有时候需要从JSON
文件里读取配置数据到内存。当JSON
文件足够大时,如果先把文件读入内存再进行parse
会浪费不必要的大文件连续内存。甚至可能会导致OOM
, 这时候如果能像XML
文件那样可以以流的方式读取结构化JSON
数据,那么会节省很多内存。那么怎么做?
说明
-
开发
jfinal
框架的网站时,标配是fastjson-1.2.83
版本,也就是fastjson 1
的最高版本。如果不是特殊的用法,这个版本是够用且稳定的。 -
JSON
文件是UTF-8
格式,一般可以用它来做多语言文字存储格式。 常用的可以通过以下方式解析指定的JSON
格式。这种方式得先有内存的JSON
格式, 这种方式需要预先读取.json
文件所有内容到内存。
JSONObject object = JSONObject.parseObject(pageDataStr);
Object object = JSON.parse(pageDataStr);
- 还有就是
fastjson
提供了Stream API JSONReader
,来按流的方式读取指定部分json
对象,比如对象,数组,字符串,整数等。
JSONReader jr = new JSONReader(Reader)){
jr.startObject();
while(jr.hasNext()){String key = jr.readString();JSONObject value = (JSONObject) jr.readObject();...
}
jr.endObject();
例子
- 以下例子读取文件的
json
格式并存储在一个大JSONObject里
。
try(InputStream is = new FileInputStream(file);InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);BufferedReader br = new BufferedReader(isr);JSONReader jr = new JSONReader(br)){JSONObject object = new JSONObject();// 明确知道`json`文件是以对象开始存储的。 {"name":"Peter"}jr.startObject();while(jr.hasNext()){String key = jr.readString();JSONObject value = (JSONObject) jr.readObject();object.put(key,value);}jr.endObject();data.put(localName,object);return true;
} catch (FileNotFoundException e) {log.error(e.getMessage());
} catch (IOException e) {log.error(e.getMessage());
}
json file
{"article": {"home":"首页","support_center":"支持中心","sales_faqs":"销售常见问题","refund_faqs":"退款常见问题","product_faqs":"产品常见问题","online_tutorials":"在线教程","product_center":"产品中心"}
}
参考
-
FastJson 读取超大json文件引起OOM问题排查与解决
-
fastjson 1
-
Quick Start CN · alibaba/fastjson Wiki
-
常见问题 · alibaba/fastjson Wiki
-
Stream api · alibaba/fastjson Wiki
-
JSON最佳实践