如何读取大型JSON文件?

时间:2017-04-17 06:40:35

标签: java json json-simple

How to read a large JSON file ?

    {   
    "Count": 361888,
    "Items": 
    [
    {   "S3Url": {"S": Grouper/1904/1/private/drafts/D1_2/siepon_D1_2/siepon_C11_D1‌​_2_diff.pdf" },
        "JSONFile": {"S": Grouper/1904/1/private/drafts/D1_2/siepon_D1_2/siepon_C11_D1‌​_2_diff.pdf.json" },
        "ErrTs": {"N": "1488010286704"}
    },
    {   "S3Url": {"S": Mentor/47200043/Public/07/11-07-1984-05-000s-june-2007-mesh-‌​ad-hoc- agenda.ppt.pdf" },
        "JSONFile": {"S": "Mentor/47200043/Public/07/11-07-1984-05-000s-june-2007- mesh-ad-hoc-agenda.ppt.pdf.json"},
        "ErrTs": {"N": "1490497271699"}
    }
    ],
    "ScannedCount": 23
    }

This is the input JSON File format. File is too large so cannot use:
*Jsonparser parser=new Jsonparser();
*Object obj=parser.parse(new FileReader(JSON_FILE_PATH))
Error is :
java.lang.OutOfMemoryError: Java heap space
increase the maximum heap size by using JVM options "-Xmx512M" won't work.
tried the code :
     jsonParser.parse(new FileReader(JSON_FILE_PATH), new ContentHandler() {
        private String key;
        private Object value;

        // A bunch of "default" methods
        @Override public void startJSON() { }
        @Override public void endJSON() { }
        @Override public boolean startObject() { return true; }
        @Override public boolean endObject() { return true; }
        @Override public boolean startArray() { return true; }
        @Override public boolean endArray() { return true; }

        @Override
        public boolean startObjectEntry(final String key) {
            this.key = key;
            return true;
        }

        @Override
        public boolean endObjectEntry() {
            System.out.println(key + " => " + value);
            return true;
        }

        @Override
        public boolean primitive(final Object value) {
            this.value = value;
            return true;
        }
    });
    }

预期产出:         key:S3Url         值:石斑鱼/ 1904/1 /私人/草稿/ D1_2 / siepon_D1_2 / siepon_C11_D1 _2_diff.pdf in excel

实际输出:     关键:S         值:excel中的Grouper / 1904/1 / private / drafts / D1_2 / siepon_D1_2 / siepon_C11_D1 _2_diff.pdf             关键:S             值:石斑鱼/ 1904/1 /私人/草稿/ D1_2 / siepon_D1_2 / siepon_C11_D1 _2_diff.pdf in excel

which is repeating. So please help to read the large Json file in required format.

2 个答案:

答案 0 :(得分:0)

由于内存泄漏可能导致此错误

如何解决java.lang.OutOfMemoryError:Java堆空间

1)在java中解决OutOfMemoryError的一种简单方法是使用JVM选项“-Xmx512M”来增加最大堆大小,这将立即解决您的OutOfMemoryError。当我在构建项目时在Eclipse,Maven或ANT中获得OutOfMemoryError时,这是我的首选解决方案,因为根据项目的大小,您可以轻松地运行Memory.here是一个增加JVM的最大堆大小的示例,还有更好的保留 - 如果在java应用程序中设置堆大小,则Xmx到-Xms比例为1:1或1:1.5

导出JVM_ARGS =“ - Xms1024m -Xmx1024m”

2)在Java中解决OutOfMemoryError的第二种方法相当困难,当你没有太多内存时甚至在增加最大堆大小之后你仍然得到java.lang.OutOfMemoryError,在这种情况下,你可能想要分析您的应用程序并查找任何内存泄漏。您可以使用Eclipse Memory Analyzer检查堆转储,也可以使用Netbeans或JProbe等任何分析器。这是一个棘手的解决方案,需要一些时间来分析和发现内存泄漏。

调查和修复Java中OutOfMemoryError的工具

1)Visualgc

2)Jmap

3)Jhat

4)Eclipse内存分析器

5)学习分析的书籍

了解详情:here

答案 1 :(得分:0)

您收到此错误是因为您的JVM无法分配足够的内存来存储JSONObject HashMap的子类的结果{并且根据堆栈跟踪很清楚) 。 虽然您声称拥有400MB的JSON文档,但与其他JSON文档相比可能会更小,并且增加内存大小对您没什么帮助。 您可以使用流式传输从JVM资源角度以几乎零成本解析给定的JSON文档,但您必须编写更复杂的代码。 com.googlecode.json-simple:json-simple使用ContentHandler s支持流式阅读。

示例:

{
    "foo": 1,
    "bar": 2
}
try ( final Reader reader = getPackageResourceReader(Q43446452.class, "document.json") ) {
    final JSONParser jsonParser = new JSONParser();
    jsonParser.parse(reader, new ContentHandler() {
        private String key;
        private Object value;

        // A bunch of "default" methods
        @Override public void startJSON() { }
        @Override public void endJSON() { }
        @Override public boolean startObject() { return true; }
        @Override public boolean endObject() { return true; }
        @Override public boolean startArray() { return true; }
        @Override public boolean endArray() { return true; }

        @Override
        public boolean startObjectEntry(final String key) {
            this.key = key;
            return true;
        }

        @Override
        public boolean endObjectEntry() {
            System.out.println(key + " => " + value);
            return true;
        }

        @Override
        public boolean primitive(final Object value) {
            this.value = value;
            return true;
        }
    });
}

当然,这是一个非常原始的例子,的成本,而不是JVM,但你可以使用这种方法解析甚至无限的JSON流。

输出:

  

foo => 1
  bar => 2