2017-02-21 41 views
3

У меня есть большой CSV-файл, размер которого не определен и может быть более 4 ГБ. Мне нужно прочитать несколько строк из файла случайно в качестве тестовых примеров для выполнения некоторых тестов в приложении.Как случайным образом читать полную строку (включая возможные разрывы строк) из большого файла csv в java

Невозможно прочитать полный файл в памяти, потому что он вызовет исключение OutOfMemoryError.

Одним из решений является создание массива некоторых чисел, падающих в диапазоне от общего числа, а затем сортировка списка. Наконец-то прочитайте файл по строке в соответствии с номером, хранящимся в массиве. Поэтому я мог получить случайный набор полных строк из файла csv.

Есть ли library или method, чтобы прочитать полную строку из файла big csvrandomly?

Одно из решений:

 // 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

Не забудьте инициализировать JVM с более высокой памятью кучи, используя переменную -Xms – Kainix

+1

Вы также можете создать случайное число 'p' между 0 (включительно) и размером файла. Затем 'seek' (например, используя [skip()] (https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#skip%28long%29)) в позицию' p' внутри файла. Оттуда сканируйте следующий EOL, затем прочитайте и верните следующую строку. – JimmyB

ответ

2

Reservoir sampling является алгоритм, который приходит на ум здесь. Самое приятное в этом состоит в том, что вам не нужно знать, сколько предметов есть, и вам не нужно читать весь файл в памяти; просто следующую строку, если необходимо.