Java 使用GSON加载非常大的流
我正在尝试读取一个非常重的JSON(超过6000个对象),并将它们存储在一个哈希映射上,以便稍后将其插入到我的数据库中 但问题是我面临OOM,这是因为我的JSON很重,然而GSON库应该让我摆脱这种情况,但事实并非如此 有什么想法吗Java 使用GSON加载非常大的流,java,android,json,gson,Java,Android,Json,Gson,我正在尝试读取一个非常重的JSON(超过6000个对象),并将它们存储在一个哈希映射上,以便稍后将其插入到我的数据库中 但问题是我面临OOM,这是因为我的JSON很重,然而GSON库应该让我摆脱这种情况,但事实并非如此 有什么想法吗 public Map<String,String> readJsonStream(InputStream in) throws IOException { JsonReader reader = new JsonReader(new Input
public Map<String,String> readJsonStream(InputStream in) throws IOException
{
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
Map<String,String> contentMap = new HashMap<String,String>();
Gson mGson = new Gson();
contentMap = mGson.fromJson(reader, contentMap.getClass());
reader.close();
return contentMap;
}
publicmap readJsonStream(InputStream-in)引发IOException
{
JsonReader=新的JsonReader(新的InputStreamReader(在“UTF-8”中));
Map contentMap=newhashmap();
Gson mGson=新的Gson();
contentMap=mGson.fromJson(reader,contentMap.getClass());
reader.close();
返回contentMap;
}
根据我的经验,是的,您可以使用google GSON来流式传输JSON数据。这是一个如何做到这一点的示例:
APIModel result = new APIModel();
try {
HttpResponse response;
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost(APIParam.API_001_PRESENT(
serial_id, api_key));
try {
response = myClient.execute(myConnection);
Reader streamReader = new InputStreamReader(response
.getEntity().getContent());
JsonReader reader = new JsonReader(streamReader);
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("result")) {
if (reader.nextString() == "NG") {
result.setResult(Util.API_001_RESULT_NG);
break;
}
} else if (name.equals("items")) {
result = readItemsArray(reader);
} else {
reader.skipValue(); // avoid some unhandle events
}
}
reader.endObject();
reader.close();
} catch (Exception e) {
e.printStackTrace();
result.setResult(Util.API_001_RESULT_NG);
}
} catch (Exception e) {
e.printStackTrace();
result.setResult(Util.API_001_RESULT_NG);
}
readItemsArray函数:
// read items array
private APIModel readItemsArray(JsonReader reader) throws IOException {
APIModel result = new APIModel();
String item_name, file_name, data;
result.setResult(Util.API_001_RESULT_OK);
reader.beginArray();
while (reader.hasNext()) {
item_name = "";
file_name = "";
data = "";
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("name")) {
item_name = reader.nextString();
} else if (name.equals("file")) {
file_name = reader.nextString();
} else if (name.equals("data")) {
data = reader.nextString();
} else {
reader.skipValue();
}
}
reader.endObject();
result.populateModel("null", item_name, file_name, data);
}
reader.endArray();
return result;
}
API模型类:
public class APIModel {
private int result;
private String error_title;
private String error_message;
private ArrayList<String> type;
private ArrayList<String> item_name;
private ArrayList<String> file_name;
private ArrayList<String> data;
public APIModel() {
result = -1;
error_title = "";
error_message = "";
setType(new ArrayList<String>());
setItem_name(new ArrayList<String>());
setFile_name(new ArrayList<String>());
setData(new ArrayList<String>());
}
public void populateModel(String type, String item_name, String file_name, String data) {
this.type.add(type);
this.item_name.add(item_name);
this.file_name.add(file_name);
this.data.add(data);
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getError_title() {
return error_title;
}
public void setError_title(String error_title) {
this.error_title = error_title;
}
public String getError_message() {
return error_message;
}
public void setError_message(String error_message) {
this.error_message = error_message;
}
public ArrayList<String> getType() {
return type;
}
public void setType(ArrayList<String> type) {
this.type = type;
}
public ArrayList<String> getItem_name() {
return item_name;
}
public void setItem_name(ArrayList<String> item_name) {
this.item_name = item_name;
}
public ArrayList<String> getFile_name() {
return file_name;
}
public void setFile_name(ArrayList<String> file_name) {
this.file_name = file_name;
}
public ArrayList<String> getData() {
return data;
}
public void setData(ArrayList<String> data) {
this.data = data;
}
}
公共类APIModel{
私有int结果;
私有字符串错误\u标题;
私有字符串错误消息;
私有数组列表类型;
私有ArrayList项_名称;
私有ArrayList文件名;
私有数组列表数据;
公共模型(){
结果=-1;
错误_title=“”;
错误消息=”;
setType(新的ArrayList());
setItem_名称(新ArrayList());
setFile_name(新的ArrayList());
setData(新的ArrayList());
}
public void populateModel(字符串类型、字符串项名称、字符串文件名称、字符串数据){
this.type.add(type);
此.item\u name.add(item\u name);
this.file\u name.add(文件名);
this.data.add(数据);
}
public int getResult(){
返回结果;
}
公共void setResult(int result){
this.result=结果;
}
公共字符串getError_title(){
返回错误标题;
}
public void setError\u title(字符串错误\u title){
this.error\u title=error\u title;
}
公共字符串getError_message(){
返回错误消息;
}
公共无效设置错误消息(字符串错误消息){
this.error\u message=错误消息;
}
公共ArrayList getType(){
返回类型;
}
公共void集合类型(ArrayList类型){
this.type=type;
}
公共阵列列表getItem_name(){
返回项目名称;
}
公共无效集合项_名称(ArrayList项_名称){
this.item\u name=item\u name;
}
公共阵列列表getFile_name(){
返回文件名;
}
public void setFile_name(ArrayList file_name){
this.file\u name=文件名;
}
公共ArrayList getData(){
返回数据;
}
公共void setData(ArrayList数据){
这个数据=数据;
}
}
在使用GoogleGSON的流式API之前,我还遇到了OOM错误,因为我得到的JSON数据是非常大的数据(许多图像和声音采用Base64编码),但通过GSON流式传输,我可以克服这个错误,因为它不会一次读取每个令牌的数据。对于Jackson JSON库,我认为它也有流式API,以及如何使用它,这与我使用google GSON的实现几乎相同。我希望我的回答能对您有所帮助,如果您对我的回答还有其他问题,请在评论中提问:)我不知道GSON是否能做到这一点,但Jackson可以做到:它有一个流式API允许您做到这一点。@fge所以您建议我使用Jackson?好吧,我已经使用了这两种方法,而且现在一直更喜欢Jackson,YMMV…@fge对不起,我应该从哪里下载它?好吧,看看@NAYOSO对Gson流媒体API的回答。如果您还没有确定下来,请尝试两种方法,然后选择您喜欢的一种;)我花了至少5分钟才意识到
Util
类是一个需要编写的枚举。在大多数情况下,您既不需要APIModel
也不需要Util
类——它们在这里作为用户试图解析的对象的示例提供。另外,值得注意的是,变量/参数/方法名称中的下划线也会断开。@gmale是的,我意识到了这一点,我在去年开始学习java时写了这段代码,我只是复制并粘贴到这里,所以请原谅我:),如果有时间,我会尝试重写!谢谢你的通知:)@nayoso:不用担心,我刚刚发布了一个帖子,以防它能为下一个人节省5分钟:)注意,我刚刚偶然发现了另一个好例子