Theme NexT works best with JavaScript enabled
0%

教你使用Gson Streaming轻松解析超大json文件

关于如何将大型Json文件解析为Java对象的指南。使用Gson Streaming读取非常大的Json文件并将其秘密转换为对象。

教程内容

  • 概述
  • 写入大型JSON文件
  • 通过流读取大型JSON文件
  • 概括

概述

Gson是一个非常流行的API,用于将JSON字符串解析为ObjectsGson提供的parse方法非常适合读取整个JSON字符串并将其一次性解析为Java Objects。为此,首先将JSON字符串加载到内存中,然后将其转换为对象。但是,当我们处理一个非常大的JSON文件时,它可能导致OutOfMemoryError。为了避免这种情况,我们可以使用Gson流技术来分块解析一个大文件。

在本教程中,我们使用Gson Streaming并将400 MB JSON文件有效地解析为Java Objects,而无需将其完全加载到内存中。我们还将监视程序消耗的内存量。但是,在执行此操作之前,让我们从快速设置开始。

写入大型JSON文件

首先,我们将使用Java程序创建一个400MB的Json文件。接下来是一个示例JSON形式的Person记录示例。

1
2
3
4
5
{
"name":"John",
"age":31,
"city":"New York"
}

我们将创建一个包含一千万个人记录的JSON数组,并将其存储到Json文件中。

1
2
3
4
5
6
7
8
9
10
11
12
FileOutputStream fos = new FileOutputStream(target);
OutputStreamWriter ow = new OutputStreamWriter(fos);
ow.write("[");

for (int i = 0; i < 10000000; i++) {
if (i != 0) {
ow.write(",");
}
ow.write(person);
}
ow.write("]");
ow.flush();

我们正在使用OutputStreamWriter将每个人记录写入文件。不要忘记关闭所有打开的流和阅读器。

通过流读取大型JSON文件

现在我们的输入JSON文件已准备就绪,我们将对其进行流传输,并使用Gson Streaming的内存高效方式将每条记录转换为Java对象。

为了流式传输Json文件,Gson提供了JsonReader类。使用此类,我们可以浏览JSON对象和嵌套对象,并将它们迭代地转换为java对象。

接下来是示例,在该示例中,我们读取大型JSON文件,遍历其内容,然后将其解析为对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
private void readLargeJson(String path) throws IOException {
try (
InputStream inputStream = Files.newInputStream(Path.of(path));
JsonReader reader = new JsonReader(new InputStreamReader(inputStream));
) {
reader.beginArray();
while (reader.hasNext()) {
Person person = new Gson().fromJson(reader, Person.class);
//System.out.println(Person);
}
reader.endArray();
}
}

首先,我们在文件上创建一个InputStream,并使用它来创建InputStreamReader。接下来,我们实例化JsonReader包装器并将其用于解析JSON文件。

当我们处理人员对象的Json数组时,我们使用beginArray()方法来流经数组元素。然后,我们遍历Json数组的所有元素,并将每个元素隐式转换为新的Person对象。最后,我们关闭数组。请注意,我们使用try-with-resources块自动关闭流和读取器。

同样,如果要处理大型Json对象,则可以使用beginObject()方法访问嵌套对象。

测试

现在,我们将使用我们创建的400MB Json文件对其进行流式处理。为了监视内存消耗,我们将在单独的线程中运行readLargeJson()方法。主线程以固定的时间间隔在控制台上以MB为单位打印可用内存量。

1
2
3
4
5
6
7
8
9
10
Source File Size 400
Memory used: 9
Memory used: 139
Memory used: 112
Memory used: 122
Memory used: 96
Memory used: 121
Memory used: 150
Memory used: 82
total time 35023

输出清楚地表明我们的内存消耗是最佳的,并且我们没有将整个JSON文件读入内存。

概括

在本快速教程中,我们学习了如何以内存有效的方式解析超大型JSON文件,以避免**OutOfMemoryError**。我们使用GSON API来流化一个400 MB的Json文件,并将其迭代地转换为Java对象。

要使用Jackson API解析Json对象,请访问将JSON字符串读取为使用Jackson API的Java对象

坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道