2017-04-10 38 views
3

JSONファイルには100万のレコードがありますが、javaJSONファイルから配列の配列を読み取る効率的で最速のメソッドが必要です。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

として保存され、この形式でこのファイルを読む必要がどのように https://www.ngdata.com/parsing-a-large-json-file-efficiently-and-easily/

をして、この - - ジャクソンストリーミングAPIに見てみてください

+1

JSONを意味しますか?または私は何かを逃している? – DazstaV3

+0

誤った入力JSON。 –

+0

まず、ファイルは高速SSD上になければなりません。次に、あなたは 'BufferedReader'でそれを読んでみて、あなたのSSDが提供できる最大速度を既に得ているかどうかを調べることができます。そうでない場合は、 'FileChannel.map'を試して、結果のByteBufferからどれくらい速く読むことができるかを見てください。 Btw。ファイルを複数回読み取る場合は、OSがメモリ内のファイル全体をバッファできるように、空き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()行を置き換えて、それに多くの時間がかかる行を実行します。私はデータをより効率的に検索するためにハッシュマップを使用したので、巨大なデータを保存し、最小限のメモリを使用して効率的に検索する手段があります。 –

2

は、私はあなたがこのような何かを探していると思いますhttps://stackoverflow.com/a/24838392/814304

主なもの - 大きなファイルがある場合は、ファイルを読み込み、処理する必要があります。

+0

質問は親切に更新されています。 –

+0

スレッド「main」の例外「java.lang.OutOfMemoryError:Java heap space」 –

+0

@AAKMファイル全体をメモリにロードせず、BufferredReaderを使用して文字列を分割します。 –

0

あなたはJsonPathにより、すべての内部JSON配列を抽出するためにJsonSurferを使用することができます:$ [*]

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配列は1つずつ処理されます。

関連する問題