读取一个巨大的 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,它实际上非常符合您的问题。