有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java读取对象的巨大json数组文件

我有一个很大的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读取此文件,然后逐个对象推送


共 (2) 个答案

  1. # 1 楼答案

    你应该看看Jackson流媒体API(https://www.baeldung.com/jackson-streaming-api)。我自己用它来处理GB的大型JSON文件。最棒的是,您可以将JSON划分为几个较小的JSON对象,然后用mapper.readTree(parser)解析它们。通过这种方式,您可以将普通Jackson的便利性与流式API的速度和可伸缩性结合起来

    与你的问题有关:

    据我所知,您有一个非常大的数组(这就是文件大小的原因)和一些可读性更强的对象:

    例如:

    [ // 40GB
    {}, // Only 400 MB
    {},
    ]
    

    你现在可以做的是用Jackson的流式API解析文件并遍历数组。但每个单独的对象都可以被解析为“常规”Jackson对象,然后就可以轻松地进行处理

    你可以看看这个Use Jackson To Stream Parse an Array of Json Objects,它实际上非常符合你的问题

  2. # 2 楼答案

    is there a way to read this file using BufferedReader and then to push object by object ?

    当然不是。即使你可以打开这个文件,你怎么能把40GB作为java对象存储在内存中呢?我认为你的计算机内存没有这么大(但从技术上讲,使用ObjectMapper你应该有大约2倍的操作内存——存储json的内存是40GB,存储结果的内存是40GB,因为java对象=80GB)

    我认为你应该使用这个questions中的任何方式,但是将信息存储在数据库或文件中,而不是存储在内存中。例如,如果json中有数百万行,则应该解析每一行并将其保存到数据库中,而不必将其全部保存在内存中。然后您可以逐步从数据库中获取这些数据(例如,每次不超过1GB)