我正在尝试使用Java和GSON解析www.example.com上的JSON格式的大型(大约10GB)数据库转储Musicbrainz.org
JSON文件是这样的结构。没有'[' ']'表示这将是一个对象数组,每个对象之间也没有','。不知道为什么,但这个JSON文件就是这样。
{
"id": "d0ab06e1-751a-414b-a976-da72670391b1",
"name": "Arcing Wires",
"sort-name": "Arcing Wires"
}
{
"id": "6f0c2c16-dd7e-4268-a484-bc7b2ac78108",
"name": "Another",
"sort-name": "Another"
}
{
"id": "e062b6cd-5506-47b0-afdb-72f4279ec38c",
"name": "Agent S",
"sort-name": "Agent S"
}
这是我使用的代码:
try(JsonReader jsonReader = new JsonReader(
new InputStreamReader(
new FileInputStream(jsonFilePath), StandardCharsets.UTF_8))) {
Gson gson = new GsonBuilder().create();
jsonReader.beginArray();
while (jsonReader.hasNext()) {
Artist mapped = gson.fromJson(jsonReader, Artist.class);
//TODO do something with the object
}
}
jsonReader.endArray();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
我Map的类是:
public class Artist {
@SerializedName("id")
public String id;
@SerializedName("name")
public String name;
@SerializedName("sort-name")
public String sortName;
}
我得到错误是:
Exception in thread "main" java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at DBLoader.parse(DBLoader.java:39)
at DBLoader.main(DBLoader.java:23)
我相信GSON期望的结构与我声明的结构不同,但是我不明白我应该如何定义这种没有逗号和括号的JSON。
2条答案
按热度按时间gk7wooem1#
默认情况下,JSON只声明一个top值(是的,这将是一个 * 有效的JSON文档 *),但是有一种 JSON流 ,它使用任意技术将多个JSON元素连接到单个流中,假设流使用者可以解析它(read more). Gson支持所谓的宽松模式,该模式关闭“仅限一个最高值”模式(并做了一些与问题无关的事情)对于
JsonReader
:setLenient
。打开宽松模式后,可以逐个读取JSON元素,结果表明,该模式可用于解析/读取 * 行分隔的JSON 和 * 连接的JSON值 ,因为它们仅由零个或多个空格分隔,而Gson会忽略这些空格(因此,不支持更奇特 * 记录分隔符分隔的JSON 和 * 长度前缀的JSON)。它不适用于您的原因是您的初始代码假定流包含单个JSON数组(显然它不包含:它应该是一个不符合JSON数组语法的元素流)。一个简单的通用JSON流支持可能如下所示(使用Stream API,因为它比
Iterator
具有更丰富的API,但是展示一个想法是很好的,您可以轻松地将其调整为迭代器、回调、可观察流,无论您喜欢什么):然后道:
输出(假设
Artist
具有Lombok生成的toString()
):艺术家(id= d 0ab 06 e1 - 751 a-414 b-a976-da 72670391 b1,名称=电弧丝,类别名称=电弧丝)
艺术家(id= 6 f0 c2 c16-dd 7 e-4268-a484-bc 7 b2 ac 78108,名称=另一个,排序名称=另一个)
艺术家(id= e062 b6 cd-5506- 47 b 0-afdb-72 f4279 ec 38 c,名称=代理S,排序名称=代理S)
这种方法,JSON流,保存了多少字节,以便在您尝试使用的服务中使用?
zpf6vheq2#
它看起来像
jsonl
,其中每行都是一个有效的JSON对象。(阅读更多here)你可以逐行读取文件并转换为对象。我认为它会起作用的。