Разбор строк в SuperCSV - PullRequest
       36

Разбор строк в SuperCSV

2 голосов
/ 28 ноября 2011

@ Карло В. Данго Я упростил свой вопрос и прочитал документацию - хороший совет, чтобы не паниковать. Тем не менее, у меня есть проблемы. Помоги мне решить одну, и она решит их все. Спасибо.

Вопрос: Когда у меня есть запись csv, в которой отсутствует поле, не являющееся строкой, как (или даже можно ли) преобразовать отсутствующую запись в значение по умолчанию или, по крайней мере, не генерировать исключение NullPointerException? Необязательный cellProcessor также не предупреждает ошибку.

Эта программа взята в основном с сайта SuperCSV.

package com.test.csv;
import java.io.FileReader;

import org.supercsv.cellprocessor.ParseBigDecimal;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;


public class CSVReader {

private static final CellProcessor[] cellProcessor = new CellProcessor[] {
    null,
    null,
    new ParseInt(),
    new ParseDate("yyyyMMdd"),      
    new ParseBigDecimal()       
};

public static void main (String[] args ) throws Exception {

    CsvPreference pref = new CsvPreference('"', '|', "\n");

    ICsvBeanReader inFile = new CsvBeanReader(new FileReader("C:\\temp\\sapfilePipe.txt"), pref);
    try {
        final String[] header = inFile.getCSVHeader(true);
        User user;
        while ((user = inFile.read(User.class, header, cellProcessor)) != null) {
            System.out.println(user);
        }
    } finally {
        inFile.close();
    }

}

}

вот файл CSV, который я читаю. Обратите внимание, что в первой записи пропущено поле (возраст).

firstName|lastName|age|hireDate|hourlyRate
A.|Smith|  |20110101|15.50

Мой пользовательский компонент:

package com.test.csv;

import java.math.BigDecimal;
import java.util.Date;

public class User {

private String firstName;
private String lastName;
private int age;
private Date hireDate;
private BigDecimal hourlyRate;
    ...getters/setters...   

Вот ошибка:

Exception in thread "main" java.lang.NullPointerException
    at org.supercsv.io.CsvBeanReader.fillObject(Unknown Source)
    at org.supercsv.io.CsvBeanReader.read(Unknown Source)
    at com.glazers.csv.CSVReader.main(CSVReader.java:31)

Спасибо.

Ответы [ 2 ]

3 голосов
/ 12 февраля 2012

Редактировать: Обновление для Super CSV 2.0.0-beta-1

Super CSV 2.0.0-beta-1 уже выпущен.Он включает в себя множество исправлений ошибок и новых функций (включая поддержку Maven и новое расширение Dozer для отображения вложенных свойств и массивов / коллекций).

Он также изменил способ обработки пустых ("") столбцов - онитеперь читаются как null.Это означает, что поля firstName и lastName в вашем компоненте теперь будут null вместо "", если они отсутствуют в файле CSV.

Процессор Optional() был обновлен, чтобы обслужить это - так что он будет по-прежнему функционировать так же.

Мое предложение использовать Token больше не актуально: вы должны использовать ConvertNullTo вместо:

new ConvertNullTo(-1, new ParseInt())

То, что вы действительно хотите, - это Optional CellProcessor, который будет выполнять следующий процессор в цепочке, только если столбец не 't empty.

Поэтому обновите ваш массив CellProcessor до:

private static final CellProcessor[] cellProcessor = new CellProcessor[] {
    null,
    null,
    new Optional(new ParseInt()),
    new ParseDate("yyyyMMdd"),      
    new ParseBigDecimal()       
};

Таким образом, ParseInt будет выполняться только в том случае, если столбец не пустой (CellProcessors выполняется слева направо),оставив поле int в компоненте со значением по умолчанию, равным 0.

Если вы хотите установить в поле значение -1, чтобы указать, что значение не было предоставлено, то вы можете использовать процессор Token, который будетзамените любой токен (в данном случае "") на желаемое значение, для любого другого ввода он перейдет к следующему процессору.то есть

new Token("", -1, new ParseInt())

@ Carlo V. Dango CsvListReader - очень примитивная реализация (и вы теряете способность отображать на bean-объекты), поэтому я бы использовал ее только для быстрого и грязного анализа.

И я бы рекомендовал использовать null в массиве (при чтении) для свойств String, которые не требуют дальнейшей обработки.

Кстати, я работаю над проектом Super CSV для предстоящегорелиз.Я обязательно улучшу примеры кода на веб-сайте, пока я на нем;)

1 голос
/ 28 ноября 2011

Читатель списка читает каждую строку в список строк. Кажется, это то, что вы ищете.

http://supercsv.sourceforge.net/javadoc/org/supercsv/io/CsvListReader.html

или как показано здесь http://supercsv.sourceforge.net/codeExamples_general.html вы можете установить процессор на ноль, если вы не хотите, чтобы что-то конкретное было сделано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...