传统的解析JSON是要完全构建好一个完整的JSON文本内容然后通过JSON框架去解析反序列化,但是当JSON内容非常长,比如,一个JSON列表中存储有N个元组,而且非常长有上万个。这样在传输JSON文本内容的时候如何实现流式传输呢?方法当然是有的,在Solr的Xport代码中有就有这样一段代码,类名是:JSONTupleStream。
import java.io.IOException; import java.io.Reader; import java.util.List; import java.util.Map; import org.apache.solr.client.solrj.io.stream.SolrStream; import org.noggit.JSONParser; import org.noggit.ObjectBuilder; public class JSONTupleStream { private List<String> path; // future... for more general stream handling private Reader reader; private JSONParser parser; private boolean atDocs; public JSONTupleStream(Reader reader) { this.reader = reader; this.parser = new JSONParser(reader); } /** returns the next Tuple or null */ public Map<String,Object> next() throws IOException { if (!atDocs) { boolean found = advanceToDocs(); atDocs = true; if (!found) return null; } // advance past ARRAY_START (in the case that we just advanced to docs, or OBJECT_END left over from the last call. int event = parser.nextEvent(); if (event == JSONParser.ARRAY_END) return null; Object o = ObjectBuilder.getVal(parser); // right now, getVal will leave the last event read as OBJECT_END return (Map<String,Object>)o; } public void close() throws IOException { reader.close(); } private void expect(int parserEventType) throws IOException { int event = parser.nextEvent(); if (event != parserEventType) { throw new IOException("JSONTupleStream: expected " + JSONParser.getEventString(parserEventType) + " but got " + JSONParser.getEventString(event) ); } } private void expect(String mapKey) { } private boolean advanceToMapKey(String key, boolean deepSearch) throws IOException { for (;;) { int event = parser.nextEvent(); switch (event) { case JSONParser.STRING: if (key != null) { String val = parser.getString(); if (key.equals(val)) { return true; } else if("error".equals(val)) { handleError(); } } break; case JSONParser.OBJECT_END: return false; case JSONParser.OBJECT_START: if (deepSearch) { boolean found = advanceToMapKey(key, true); if (found) { return true; } } else { advanceToMapKey(null, false); } break; case JSONParser.ARRAY_START: skipArray(key, deepSearch); break; } } } private void handleError() throws IOException { for (;;) { int event = parser.nextEvent(); if(event == JSONParser.STRING) { String val = parser.getString(); if("msg".equals(val)) { event = parser.nextEvent(); if(event == JSONParser.STRING) { String msg = parser.getString(); if(msg != null) { throw new SolrStream.HandledException(msg); } } } } else if (event == JSONParser.OBJECT_END) { throw new IOException(""); } } } private void skipArray(String key, boolean deepSearch) throws IOException { for (;;) { int event = parser.nextEvent(); switch (event) { case JSONParser.OBJECT_START: advanceToMapKey(key, deepSearch); break; case JSONParser.ARRAY_START: skipArray(key, deepSearch); break; case JSONParser.ARRAY_END: return; } } } private boolean advanceToDocs() throws IOException { expect(JSONParser.OBJECT_START); advanceToMapKey("numFound", true); expect(JSONParser.LONG); // int event = parser.nextEvent(); //if (event == JSONParser.ARRAY_END) return null; System.out.println( ObjectBuilder.getVal(parser)); boolean found = advanceToMapKey("docs", true); expect(JSONParser.ARRAY_START); return found; } }
再写一段测脚本:
import java.io.StringReader; import java.util.Map; import com.dfire.tis.solrextend.core.JSONTupleStream; import junit.framework.TestCase; public class TestTupleStreamParser extends TestCase { public void test() throws Exception { StringReader reader = new StringReader("{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":" + 100 + ", \"docs\":[{name:'baisui'},{name:'xxxx'}]}"); JSONTupleStream tupleStream = new JSONTupleStream(reader); while (true) { Map<String, Object> tuple = tupleStream.next(); if (tuple != null) { System.out.println(tuple.get("name")); } else { break; } } } }
这样就可以做到,发送端不停得发送,客户端可以做到不断的去消费,这样做的好处是,当服务端客户端传输大量结构化数据的时候,可以避免首先要先开辟一个很大的内存空间,这样可以有效防止对内存溢出,同时,也可以有效提高系统吞吐率。
相关推荐
这是一个流式JSON解析器。 有关基于sax的简单版本,请参见以下要点: : MIT许可证(MIT)版权所有(c)2011-2012 Tim Caswell 特此免费授予获得此软件和相关文档文件(“软件”)副本的任何人无限制地处理软件的...
为了在Java中解析JSON,我们需要引入特定的库,这些库提供了API来帮助我们将JSON字符串转换为Java对象,反之亦然。标题提到的是“java解析json所需jar包”,这意味着我们将讨论Java中用于处理JSON的第三方库及其对应...
SAX(Simple API for XML)是一种基于事件驱动的XML解析器,适用于处理大型XML文档,因为它不会将整个文档加载到内存中。 标题中提到的"XML通过SAX解析为JSON格式"是指使用SAX解析器来读取XML文档,并将其转换成...
使用Gson,你可以通过以下方式解析JSON: ```java import com.google.gson.Gson; public class User { private String name; private int age; // getters and setters } String jsonString = "{\"name\":\...
6. **性能优化**:对于大量JSON数据,可以考虑使用流式解析(如Gson的`JsonReader`)以减少内存消耗。另外,缓存已解析过的数据,避免重复解析,也能提升性能。 7. **数据绑定框架**:如Butter Knife、Data Binding...
在“Android解析json速度对比”的测试中,我们通常会设置一个标准的JSON数据集,然后使用这三个库进行反序列化操作,并记录每种库所花费的时间。测试方法可能包括以下步骤: 1. **数据准备**:创建一个包含大量键值...
2. **内存效率**:避免一次性加载大量数据,可以使用流式解析或分块处理大JSON文件,减少内存占用。 3. **性能优化**:选择高效的解析库,比如Java的Gson库或C++的RapidJSON库,它们提供了更快速的解析速度。 4. *...
4. **Android的内置解析器:JsonParser**:Android SDK还提供了一个`JsonParser`类,允许你以流式的方式解析JSON。这对于处理大体积的JSON数据特别有用,因为它不需要一次性加载整个JSON到内存中。 ```java ...
本压缩包包含了7个用于Java解析JSON文件的必备jar包,通过解压并将这些jar包添加到您的项目类路径中,您可以轻松实现JSON处理。 1. **Jackson库**: - Jackson是Java最流行的JSON处理库之一,由 FasterXML 组织...
7. **流式API**: Gson还提供了流式API,允许你逐行读取和写入JSON,这对于处理大型JSON文件或进行增量解析很有用。 8. **GsonBuilder**: `GsonBuilder`允许你配置Gson实例的行为,如设置日期格式、启用或禁用某些...
- 数据流处理:在网络传输或文件流中,实时解析JSON数据进行处理或存储。 - API接口:服务器接收大量JSON请求时,流式解析可以降低内存消耗并提高响应速度。 总的来说,Go-jstream是一个强大的工具,为Go开发者提供...
当处理大量JSON数据时,应考虑性能优化,如使用流式解析,避免一次性加载整个JSON字符串到内存。 通过这个“Android解析json_dome.zip”源码,你可以深入理解各种JSON解析方法,并根据项目的实际需求选择合适的...
1. `org.json`库:Android SDK自带的JSON解析库,提供了`JSONObject`和`JSONArray`类,可以方便地解析JSON字符串并从中获取数据。 2. `com.google.code.gson`: Google提供的Gson库,可以将Java对象直接转换为JSON...
在使用QJson库时,需要注意的是,QJsonDocument在处理大型JSON文件时可能会消耗较多内存,因为它会一次性加载整个JSON内容。因此,对于大数据量的JSON,可能需要分块读取或使用流式解析的方式。 在实际项目中,...
JsonReader提供了一种逐字段解析JSON字符串的方法,而JsonWriter则允许我们逐步构建一个JSON结构。这两个类在处理大量或复杂JSON数据时特别有用,可以避免一次性加载整个JSON字符串到内存中。 在Unity3D环境中,...
例如,使用流式解析(Gson的`JsonReader`或Jackson的`JsonParser`)可以减少内存消耗。 8. JSON Schema:这是一种规范,用于定义JSON数据的结构和约束。配合使用,可以对JSON数据进行验证,确保其符合特定的要求。 ...
它提供了流式解析和直接映射到C++对象的能力,使得JSON数据与C++对象的转换变得直观。 3. **JsonCpp**:这个库支持C++98和C++11,提供了一个简单的API来读写JSON。它可以将JSON数据解析为C++的对象,也可以将C++...
- **解析JSON**:你可以使用Json::Reader类将JSON字符串解析为Json::Value对象,如果解析成功,Reader会返回true,否则抛出异常。 - **构造JSON**:使用Json::Value对象,你可以构建JSON结构,并通过Json::...
本文将深入探讨如何使用C#来解析JSON文件。 JSON是一种数据交换格式,其设计目标是为了便于人阅读和编写,同时也方便机器解析和生成。JSON语法基于JavaScript语法,但它是独立于语言的。JSON数据结构主要包括对象...
要使用Jackson解析JSON,首先需要添加Jackson的依赖库到项目中。如果你的项目是Maven项目,可以在pom.xml文件中添加以下依赖: ```xml <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-...