Обработка CSV файла за ограниченную память

Есть csv файл размером 1мб (7к строк). Необходимо его отфильтровать по заданной строке, но требуется использовать не более 9мб хипа. Пытался через BufferedReader, когда фильтрую все строки то укладываюсь в память (7мб), но если задаю параметр и в следствии фильтрую меньшее кол-во строк, используется уже 13мб. Как можно бы вписаться в память.

       List<String[]> lines;
       BufferedReader reader = null;
       try {
           reader = new BufferedReader(new FileReader(fileName));
           lines = new  ArrayList<>();
           String tmp;
           String[] list1;
           while ((tmp = reader.readLine()) != null) {
               list1 = tmp.split(",");
               if (list1[numberCols].contains("\"" + input)) {
                   lines.add(list1);
               }
           }
       }finally {
           assert reader != null;
           reader.close();
       }

Ответы (1 шт):

Автор решения: Дмитрий

Во-первых, нужен рефакторинг. Чем проще код, тем легче его править. Во-вторых, уберите бесполезную конкатинацию в цикле """ + input - это жрет вашу память. В-третьих, определитесь с размером буфера, по умолчанию он 8192, я далек от мысли, что нужно столько и установил 1024, но вы можете это подкорректрировать. В-четвертых, вы можете в конструктор ArrayList передать числовое значение для инициализации исходного размера, если имеете представление о приблизительном размере данной коллекции, это избавит от необходимости пересоздавать, который инкапсулирован в ArrayList, массив и копировать данные.

public static List<String[]> parse(String fileName, Integer numberCols, String input) throws IOException {
    List<String[]> lines = new ArrayList<>();
    input = "\"" + input;
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName), 1024)) {
        String tmp;
        while ((tmp = reader.readLine()) != null) {
            String[] line = tmp.split(",");
            if (line[numberCols].contains(input)) lines.add(line);
        }
    }
    return lines;
}
→ Ссылка