• 超大JSON文件解析方案(Java)


    解析超大JSON文件

    1、需求

    最近项目中需要将一个一个大于800M的JSON文件导出到Excel中,试过普通的按行读取文件和JSONReader流读取文件,由于JSON文件实在过于庞大,导致OOM问题

    2、解决方案

    每个json数组中包含的json对象太多,导致用流和按行读取时加载到内存会导致内存溢出。.

    最终采用了JsonToken的解决方案。

    package com.godfrey.poi.util;
    
    
    import com.fasterxml.jackson.core.JsonFactory;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonToken;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.MappingJsonFactory;
    
    import java.io.File;
    
    /**
     * @author godfrey
     * @since 2021-12-05
     */
    public class ParseJsonUtil {
        public static void main(String[] args) throws Exception {
            JsonFactory f = new MappingJsonFactory();
            JsonParser jp = f.createJsonParser(new File("F:/FeaturesToJSON.json"));
            JsonToken current;
            current = jp.nextToken();
            if (current != JsonToken.START_OBJECT) {
                System.out.println("Error: root should be object: quiting.");
                return;
            }
            while (jp.nextToken() != JsonToken.END_OBJECT) {
                String fieldName = jp.getCurrentName();
                // move from field name to field value
                current = jp.nextToken();
                if ("features".equals(fieldName)) {
                    if (current == JsonToken.START_ARRAY) {
                        // For each of the records in the array
                        while (jp.nextToken() != JsonToken.END_ARRAY) {
                            // read the record into a tree model,
                            // this moves the parsing position to the end of it
                            JsonNode node = jp.readValueAsTree();
                            // And now we have random access to everything in the object
                            System.out.println("field1: " + node.get("field1").asText());
                            System.out.println("field2: " + node.get("field2").asText());
                        }
                    } else {
                        System.out.println("Error: records should be an array: skipping.");
                        jp.skipChildren();
                    }
                } else {
                    System.out.println("Unprocessed property: " + fieldName);
                    jp.skipChildren();
                }
            }
        }
    }
    

    代码中使用流和树模型解析的组合读取此文件。 每个单独的记录都以树形结构读取,但文件永远不会完整地读入内存,因此JVM内存不会爆炸。最终解决了读取超大文件的问题。

  • 相关阅读:
    一个很好的命令行分享网站
    Docker inside Docker 基于 Alpine Linux
    CentOS 下运行Docker 内执行 docker build 命令的简单方法
    CentOS 安装 Harbor的简单过程(仅使用http 未使用https)
    [财务会计] 表外科目
    jira 插件介绍地址
    Linux 下安装nginx的总结 (之前写的有问题))
    Jira 的 数据库备份恢复 简单过程
    Jira 7.2.4简单安装过程
    Tomcat绑定具体IP
  • 原文地址:https://www.cnblogs.com/fm98/p/15679120.html
Copyright © 2020-2023  润新知