读取一个巨大的 json 对象数组文件
Read a huge json array file of objects
我有一个很大的 json 文件,大约 ~40Gb。当我尝试将这个对象数组文件转换为 java 对象列表时,它崩溃了。我已经使用了所有大小的最大堆 xmx
但没有任何效果!
public Set<Interlocutor> readJsonInterlocutorsToPersist() {
String userHome = System.getProperty(USER_HOME);
log.debug("Read file interlocutors "+userHome);
try {
ObjectMapper mapper = new ObjectMapper();
// JSON file to Java object
Set<Interlocutor> interlocutorDeEntities = mapper.readValue(
new File(userHome + INTERLOCUTORS_TO_PERSIST),
new TypeReference<Set<Interlocutor>>() {
});
return interlocutorDeEntities;
} catch (Exception e) {
log.error("Exception while Reading InterlocutorsToPersist file.",
e.getMessage());
return null;
}
}
有没有办法使用 BufferedReader
读取此文件,然后逐个推送对象?
is there a way to read this file using BufferedReader and then to push
object by object ?
当然不是。即使您可以打开此文件,您如何将 40GB 作为 java 对象存储在内存中?我认为你的电脑没有这么大的内存(但从技术上讲,使用 ObjectMapper
你应该有大约 2 倍的操作内存 - 40GB 用于存储 json + 40GB 用于存储结果 java 对象 = 80 GB).
我认为您应该使用此 questions 中的任何方式,但将信息存储在数据库或文件中而不是内存中。例如,如果 json 中有数百万行,则应解析每一行并将其保存到数据库中,而不是将其全部保存在内存中。然后就可以一步步从数据库中获取这些数据了(比如每次不超过1GB)。
您绝对应该看看 Jackson Streaming API (https://www.baeldung.com/jackson-streaming-api)。我自己将它用于 GB 大 JSON 文件。很棒的是,您可以将 JSON 分成几个较小的 JSON 对象,然后用 mapper.readTree(parser)
解析它们。这样您就可以将普通 Jackson 的便利性与 Streaming API.
的速度和可扩展性结合起来
与您的问题相关:
我知道你有一个非常大的数组(这是文件大小的原因)和一些更易读的对象:
例如:
[ // 40GB
{}, // Only 400 MB
{},
]
您现在可以做的是使用 Jackson's Streaming API 解析文件并遍历数组。但是每个单独的对象都可以被解析为“常规”Jackson 对象,然后轻松处理。
您可以看看这个 Use Jackson To Stream Parse an Array of Json Objects,它实际上非常符合您的问题。
我有一个很大的 json 文件,大约 ~40Gb。当我尝试将这个对象数组文件转换为 java 对象列表时,它崩溃了。我已经使用了所有大小的最大堆 xmx
但没有任何效果!
public Set<Interlocutor> readJsonInterlocutorsToPersist() {
String userHome = System.getProperty(USER_HOME);
log.debug("Read file interlocutors "+userHome);
try {
ObjectMapper mapper = new ObjectMapper();
// JSON file to Java object
Set<Interlocutor> interlocutorDeEntities = mapper.readValue(
new File(userHome + INTERLOCUTORS_TO_PERSIST),
new TypeReference<Set<Interlocutor>>() {
});
return interlocutorDeEntities;
} catch (Exception e) {
log.error("Exception while Reading InterlocutorsToPersist file.",
e.getMessage());
return null;
}
}
有没有办法使用 BufferedReader
读取此文件,然后逐个推送对象?
is there a way to read this file using BufferedReader and then to push object by object ?
当然不是。即使您可以打开此文件,您如何将 40GB 作为 java 对象存储在内存中?我认为你的电脑没有这么大的内存(但从技术上讲,使用 ObjectMapper
你应该有大约 2 倍的操作内存 - 40GB 用于存储 json + 40GB 用于存储结果 java 对象 = 80 GB).
我认为您应该使用此 questions 中的任何方式,但将信息存储在数据库或文件中而不是内存中。例如,如果 json 中有数百万行,则应解析每一行并将其保存到数据库中,而不是将其全部保存在内存中。然后就可以一步步从数据库中获取这些数据了(比如每次不超过1GB)。
您绝对应该看看 Jackson Streaming API (https://www.baeldung.com/jackson-streaming-api)。我自己将它用于 GB 大 JSON 文件。很棒的是,您可以将 JSON 分成几个较小的 JSON 对象,然后用 mapper.readTree(parser)
解析它们。这样您就可以将普通 Jackson 的便利性与 Streaming API.
与您的问题相关:
我知道你有一个非常大的数组(这是文件大小的原因)和一些更易读的对象:
例如:
[ // 40GB
{}, // Only 400 MB
{},
]
您现在可以做的是使用 Jackson's Streaming API 解析文件并遍历数组。但是每个单独的对象都可以被解析为“常规”Jackson 对象,然后轻松处理。
您可以看看这个 Use Jackson To Stream Parse an Array of Json Objects,它实际上非常符合您的问题。