Есть ли способ получить csvSchema, используемый cvsMapper, когда он читается из первой строки файла? - PullRequest
1 голос
/ 21 мая 2019

У меня есть CsvSchema и CsvMapper, настроенные на чтение CSV файлов с именами столбцов в первой строке.

Мне нужно уметь работать с данными, изменять определенные поля, а затем записывать данные обратно, сохраняя порядок столбцов.Я предполагаю, что CsvMapper имеет внутреннюю схему, которую он создает из первой строки, поскольку на карте есть все правильные пары key-value.Итак, есть ли способ использовать writer функции CsvMapper, которые будут использовать эту схему для упорядочивания данных для вывода?

CsvSchema schema = CsvSchema.emptySchema().withHeader();
CsvMapper mapper = new CsvMapper();
MappingIterator<Map<String, String>> it = this.mapper.readerFor(Map.class)
            .with(this.schema)
            .readValues(stream);

Сейчас я получаю CsvMappingException для«Нераспознанный столбец» в первом столбце данных, поэтому похоже, что он не использует схему.

1 Ответ

0 голосов
/ 21 мая 2019

Вы можете построить SequenceWriter, используя схему из первой строки, которую вы читаете из входного файла. Jackson использует LinkedHashMap , поэтому порядок сохраняется. Предположим, что ваш CSV вход содержит:

C1,name,type
I1,John,T1
I2,Adam,T2

Вы можете читать, обновлять и записывать в консоль, как в следующем примере:

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SequenceWriter;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.Map;

public class CsvApp {

    private CsvMapper csvMapper = new CsvMapper();

    private void handle() throws Exception {
        File csvFile = new File("./resource/test.csv").getAbsoluteFile();

        CsvSchema schema = CsvSchema.emptySchema().withHeader();
        MappingIterator<Map<String, String>> iterator = csvMapper.readerFor(Map.class).with(schema).readValues(csvFile);

        SequenceWriter writer = null;
        while (iterator.hasNext()) {
            final Map<String, String> row = iterator.next();
            if (writer == null) {
                writer = createWriter(row).writeValues(System.out);
            }

            // do something ...
            for (Map.Entry<String, String> item : row.entrySet()) {
                row.replace(item.getKey(), item.getValue() + "U");
            }

            // write back
            writer.write(row);
        }

        close(writer);
    }

    private ObjectWriter createWriter(Map<String, String> row) {
        CsvSchema.Builder writeSchema = new CsvSchema.Builder();
        writeSchema.setUseHeader(true);
        row.keySet().forEach(writeSchema::addColumn);

        return csvMapper.writerFor(Map.class).with(writeSchema.build());
    }

    private void close(Closeable closeable) throws IOException {
        if (closeable != null) {
            closeable.close();
        }
    }

    public static void main(String[] args) throws Exception {
        new CsvApp().handle();
    }
}

Над отпечатками кодов:

C1,name,type
I1U,JohnU,T1U
I2U,AdamU,T2U

Смотри также:

  1. текстовые форматы Джексона - Обзор
...