Я работаю над приложением, которое обрабатывает большие файлы CSV (несколько сотен МБ). Недавно я столкнулся с проблемой, которая сначала выглядела как утечка памяти в приложении, но после некоторого расследования оказалось, что это комбинация плохо отформатированного CSV и попытки CsvListReader разобрать бесконечную строку. В результате я получил следующее исключение:
at java.lang.OutOfMemoryError.<init>(<unknown string>)
at java.util.Arrays.copyOf(<unknown string>)
Local Variable: char[]#13624
at java.lang.AbstractStringBuilder.expandCapacity(<unknown string>)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(<unknown string>)
at java.lang.AbstractStringBuilder.append(<unknown string>)
at java.lang.StringBuilder.append(<unknown string>)
Local Variable: java.lang.StringBuilder#3
at org.supercsv.io.Tokenizer.readStringList(<unknown string>)
Local Variable: java.util.ArrayList#642
Local Variable: org.supercsv.io.Tokenizer#1
Local Variable: org.supercsv.io.PARSERSTATE#2
Local Variable: java.lang.String#14960
at org.supercsv.io.CsvListReader.read(<unknown string>)
Анализируя дамп кучи и файл CSV на основе результатов дампа, я заметил, что в одном из столбцов в одной из строк CSV отсутствовали закрывающие кавычки, что, очевидно, приводило к тому, что читатель пытался найти конец строки, добавляя содержимое файла во внутренний строковый буфер, пока не будет больше не было кучи памяти.
Во всяком случае, это была проблема, и это было из-за плохо отформатированного CSV - как только я удалил критическую строку, проблема исчезла. Чего я хочу добиться, так это сказать читателю, что:
- Весь контент, который он должен интерпретировать, всегда заканчивается символом новой строки, даже если кавычки не закрыты должным образом (без многострочной поддержки).
- В качестве альтернативы, чтобы обеспечить определенный предел (в байтах) строки CSV
Есть ли какой-то четкий способ сделать это в SuperCSV с помощью CsvListReader (предпочтительнее в моем случае)?