2013-06-14 2 views
2

Я использую SuperCSV для анализа записей CSV в Object. Мои CSV-файлы имеют дополнительный столбец в конце, и я хочу обработать только первые X столбцов. Поэтому я определяю отображение String[] для первых X столбцов и CellProcessor[] того же размера. Но, похоже, это не работает и выдает исключение, что количество процессоров ячеек должно быть точно таким же, как и количество столбцов.Игнорировать дополнительные столбцы в csv - SuperCSV

Может кто-нибудь сказать мне, если я что-то упустил. Нужно ли определять массив отображения, чтобы иметь одинаковые столбцы, как в пяти, даже если я их не хочу?

public CsvToBeanParser(Reader reader, Class<T> type, CsvPreference preference, CellProcessor[] cellProcessors, String[] mapping, boolean skipHeader) 
     throws IOException { 
    this.beanReader = new CsvBeanReader(reader, preference); 
    this.mapping = mapping; 
    if (skipHeader) { 
     beanReader.getHeader(true); 
    } 
    this.cellProcessors = cellProcessors; 
    this.type = type; 

} 

/** 
* Parse and return record. 
* 
* @return 
* @throws Exception 
*    if there is any parsing error 
*/ 
public T getItem() throws Exception { 
    try { 
     return (T) beanReader.read(type, mapping, cellProcessors); 
    } catch (Exception e) { 
     LOG.error("Error parsing record", e); 
     throw e; 
    } 
} 

Вот мои картографирования и клеточные процессоры

String[] mapping = {"column1", "column2"}; 
CellProcessor[] cellProcessors = {null, null}; 

Это работает для файла

column1, column2 
1,2 

, но не для (где я хочу, чтобы игнорировать колонка3)

column1, column2, column3 
1,2,3 
+0

Не могли бы вы разместить немного кода, чтобы мы могли посмотреть? – Houdini

+0

Также вы используете 'AbstractCsvReader'? – Houdini

+0

Я использую CsvBeanReader – RandomQuestion

ответ

3

Если вы используете заголовок файла CSV fil e как nameMapping, тогда вам никогда не понадобится знать, сколько столбцов есть, вы просто их используете. Если они не подходят для сопоставления (их имена не соответствуют установщикам в вашем компоненте), то вам необходимо предоставить свое собственное nameMapping с правильным количеством элементов.

Если у вашего CSV-файла есть заголовок, и вы знаете, что вам нужны только первые 2 столбца, вы можете просто предоставить массив имен (и, возможно, массив ячеек), того же размера, что и заголовок, но только с первые два элемента заполнены.

String[] header = beanReader.getHeader(true); 

// only interested in first 2 columns (rest set to null) 
String[] nameMapping = 
    Arrays.copyOf(new String[]{"column1","column2"}, header.length); 

// processors are optional, but you can populate these if you want 
CellProcessor[] processors = new CellProcessor[header.length]; 

// TODO: read your CSV here... 
+0

Спасибо, я обязательно попробую это. Я могу изменить свой файл, чтобы иметь заголовки. Любопытно, что бы я сделал, если у моего файла не было заголовка? – RandomQuestion

+0

Вы можете прочитать файл дважды (первый раз просто прочитайте первую строку, чтобы увидеть, сколько столбцов есть, а во-вторых, чтобы прочитать весь файл). –

0

Если у вас нет доступа к заголовку или разборе очень большой файл, вы можете сделать следующее:

Просто продлить CsvBeanReader

public class FlexibleCsvBeanReader extends CsvBeanReader { 

    public FlexibleCsvBeanReader(final Reader reader, final CsvPreference preferences) { 
     super(reader, preferences); 
    } 

    @Override 
    protected List<Object> executeProcessors(final List<Object> processedColumns, final CellProcessor[] processors) { 
//  we have to make sure that processors.length is equal to columnSize (thats the real column-count of the csv) 
     final int columnSize = getColumns().size(); 
//  resize the array 
     final CellProcessor[] newProcessors = new CellProcessor[columnSize]; 
     System.arraycopy(processors, 0, newProcessors, 0, processors.length); 
//  do default stuff 
     return super.executeProcessors(processedColumns, newProcessors); 
    } 
} 

namemapping можно игнорировать до тех пор, поскольку новые столбцы находятся только в конце. Если вы считаете, что это плохая практика, вы должны переопределить метод read.

Вы также можете кэшировать измененный массив, потому что в зависимости от ваших процессоров это может занять некоторое время. Но это имеет смысл только в том случае, если вы применяете для каждой строки тот же массив CellProcessor.

Смежные вопросы