2017-02-21 5 views
3

サイズが固有でなく、おそらく4 GBを超える大きなCSVファイルがあります。 ファイルからランダムにというファイルをいくつか読み込んで、アプリケーションでいくつかのテストを行う必要があります。Javaの大きなcsvファイルから完全な行(可能な改行を含む)をランダムに読み取る方法

OutOfMemoryError例外が発生するため、メモリ内の全ファイルを読むことは不可能です。

1つの解決策は、合計数の範囲内にあるいくつかの数値の配列を生成し、リストをソートすることです。 最後に、配列に格納された番号に従って、行単位でファイルから読み込みます。だから、私はcsvファイルから完全な行のランダムなセットを得ることができました。

big csvファイルrandomlyから完全な行を読み取るためにlibraryまたはmethodがありますか?

一つの解決策:

 // generate random numbers 
     List<Integer> indexList = new ArrayList<>(); 
     for (int i = 0; i < testCount; i++) { 
      int random = faker.numberBetween(0, total); 
      indexList.add(random); 
     } 

     // sort 
     Collections.sort(indexList); 

     // read from a file 
     List<String> list = new ArrayList<>(); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.csv"), "UTF-8")); 

     String line; 
     int lineNum = 0; 
     int pos = 0; 
     int currentNum = indexList.get(pos); 
     while ((line = reader.readLine()) != null) { 

      while (currentNum == lineNum) { 

       list.add(line); 
       pos++; 

       if (pos == testCount) 
        break; 

       currentNum = indexList.get(pos); 
      } 

      if (pos == testCount) 
       break; 

      lineNum++; 
     } 

     reader.close(); 
+1

ソリューションのプロセスを容易にするために実装した試しとコードを追加してください。 – webmaster

+0

-Xms変数 – Kainix

+1

を使用して、より高いヒープメモリを持つJVMを初期化することを忘れないでください。0(包括的)とファイルのサイズの間に乱数 'p'を生成することもできます。次に、「シーク」(たとえば、[スキップ()](https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#skip%28long%29)を使用して)ファイル内に「p」を挿入します。そこから次のEOLをスキャンし、次の行を読み込んで返します。 – JimmyB

答えて

2

Reservoir samplingがここに頭に浮かぶのアルゴリズムです。これについての良い点は、そこにいくつのアイテムがあるかを知る必要はなく、ファイル全体をメモリに読み込む必要はないということです。必要に応じて次の行だけを入力します。

関連する問題