2017-04-10 71 views
3

我在JSON文件中有100百万条记录,需要一个有效且最快的方法来从JSON文件中读取java中的数组阵列。在Java中按行读取大型JSON文件的快速高效的方法

JSON文件的样子:

[["XYZ",...,"ABC"],["XYZ",...,"ABC"],["XYZ",...,"ABC"],...,["XYZ",...,"ABC"], 
["XYZ",...,"ABC"],["XYZ",...,"ABC"],["XYZ",...,"ABC"],...,["XYZ",...,"ABC"], 
... 
... 
... 
,["XYZ",...,"ABC"],["XYZ",...,"ABC"],["XYZ",...,"ABC"]] 

我想按行读入此JSON文件行:

首先阅读:

["XYZ",...,"ABC"] 

则:

["XYZ",...,"ABC"] 

等等:”

... 
... 
... 
["XYZ",...,"ABC"] 

如何阅读一JSON文件是这样的,我知道这不是完全像一个JSON文件,但我需要这种格式是另存为以.json

阅读该文件
+1

你的意思是JSON?或者我错过了什么? – DazstaV3

+0

输入错误抱歉JSON。 –

+0

首先,该文件应该位于快速SSD上。接下来,您可以尝试使用'BufferedReader'读取它,看看它是否已经为您提供了SSD能够提供的最大速度。如果不尝试'FileChannel.map',看看你能从结果ByteBuffer读取多快。顺便说一句。如果您想多次读取该文件,请确保您的计算机上有足够的可用RAM,以允许操作系统将整个文件缓冲在内存中。 – SpiderPig

回答

3

您可以使用JSON Processing API (JSR 353),处理以流方式将数据:

import javax.json.Json; 
import javax.json.stream.JsonParser; 

... 

String dataPath = "data.json"; 

try(JsonParser parser = Json.createParser(new FileReader(dataPath))) { 
    List<String> row = new ArrayList<>(); 

    while(parser.hasNext()) { 
     JsonParser.Event event = parser.next(); 
     switch(event) { 
      case START_ARRAY: 
       continue; 
      case VALUE_STRING: 
       row.add(parser.getString()); 
       break; 
      case END_ARRAY: 
       if(!row.isEmpty()) { 
        //Do something with the current row of data 
        System.out.println(row); 

        //Reset it (prepare for the new row) 
        row.clear(); 
       } 
       break; 
      default: 
       throw new IllegalStateException("Unexpected JSON event: " + event); 
     } 
    } 
} 
+0

我声明了一个HashMap并将这些行值放入HashMap中,但如果我想在HashMap中获取一个值,它将返回一个空的List []。这是由于row.clear()语句引起的。如何解决这个问题? –

+0

@AAKM然后重新创建行,而不是清除它:'row = new ArrayList <>()'(在END_ARRAY块中)。而且你最好确保你有足够的内存在一个巨大的HashMap中存储1亿条记录。 – zeppelin

+0

替换row.clear()行然后执行它需要很多时间。我使用hashmap来更高效地搜索数据,所以还有其他方法来存储大量数据并通过使用最小内存进行高效搜索。 –

2

请把杰克逊流API一看,

我猜你正在寻找这样的事情 - https://www.ngdata.com/parsing-a-large-json-file-efficiently-and-easily/

这 - https://stackoverflow.com/a/24838392/814304

主要的事情 - 如果你有一个大文件,你需要阅读和处理文件懒散,一片一片。

+0

问题已更新,请再次通过。 –

+0

线程“main”中的异常java.lang.OutOfMemoryError:Java堆空间 –

+0

@AAKM不要将整个文件加载到内存中,使用BufferredReader并拆分字符串。 –

0

您可以使用JsonSurfer提取所有内JSON阵列由JsonPath:$ [*]

JsonSurfer surfer = JsonSurferJackson.INSTANCE; 
    surfer.configBuilder().bind("$[*]", new JsonPathListener() { 
     @Override 
     public void onValue(Object value, ParsingContext context) { 
      System.out.println(value); 
     } 
    }).buildAndSurf(json); 

它不会将整个Json加载到内存中。 JSON数组将被逐个处理。

相关问题