Как избежать срабатывания исключения ArrayIndexOutOfBoundsException при разборе пустых позиций в строке CSV?

String[] values = line.split(",");

Long locId = Long.parseLong(replaceQuotes(values[0]));
String country = replaceQuotes(values[1]);
String region = replaceQuotes(values[2]);
String city = replaceQuotes(values[3]);
String postalCode = replaceQuotes(values[4]);
String latitude = replaceQuotes(values[5]);
String longitude = replaceQuotes(values[6]);
String metroCode = replaceQuotes(values[7]);
String areaCode = replaceQuotes(values[8]);

//...

public String replaceQuotes(String txt){
    txt = txt.replaceAll("\"", "");
    return txt;
}

Я использую приведенный выше код для анализа CSV с данными в этом формате:

828,"US","IL","Melrose Park","60160",41.9050,-87.8641,602,708

Однако, когда я встречаю строку данных, подобную следующей, я получаю java.lang.ArrayIndexOutOfBoundsException: 7

1,"O1","","","",0.0000,0.0000,,

Означает ли это, что каждый раз, когда я даже пытаюсь получить доступ к значению в values[7], будет выдано исключение?

Если да, то как мне анализировать строки, которые не содержат данных в этой позиции текстовой строки?


person Percy    schedule 05.07.2011    source источник


Ответы (2)


Во-первых, String.split() не лучший синтаксический анализатор CSV: он не знает о кавычках и испортится, как только одно из ваших значений в кавычках будет содержать запятую.

При этом по умолчанию String.split() пропускает пустые конечные элементы. Вы можете повлиять на это, используя вариант с двумя аргументами:

String[] values = line.split(",", -1);
  • -1 (или любое отрицательное значение) означает, что массив будет настолько большим, насколько это необходимо.
  • Использование положительного значения дает максимальное количество разбиений, которое необходимо выполнить (это означает, что все, что находится за этим значением, будет одним значением, даже если оно содержит запятую).
  • 0 (по умолчанию, если вы используете значение с одним аргументом) означает, что массив будет настолько большим, насколько необходимо, но пустые конечные значения будут исключены из массива (именно так, как это происходит у вас) .
person Joachim Sauer    schedule 05.07.2011

Как правило, вы никогда не должны взламывать свой собственный (неисправный) парсер, если рабочий уже существует. CSV нелегко правильно проанализировать, и String.split не выполнит эту работу, поскольку CSV позволяет использовать , между ", не работая в качестве разделителей.

Рассмотрите возможность использования OpenCSV. Это решит как проблему, которая у вас есть сейчас, так и проблему, с которой вы столкнетесь, когда пользователь использует , как часть данных.

person Mathias Schwarz    schedule 05.07.2011