Univocity - как разобрать 3(n) строки в одну строку (bean)

Я оцениваю синтаксический анализатор Univocity для одного из моих проектов. Формат плоского файла с фиксированной шириной делает одну запись (Bean) из трех подробных записей (например, начинается с AA, BB, CC) - будет ли этот файл анализироваться с помощью Univocity?
я могу использовать recordEndsOnNewline продолжить чтение и добавить некоторые пользовательские преобразования, но есть ли какие-либо из коробки ParserSettings?

AA1234 data
BBmore data
CCsome more data row 1 ended
AA5678 data
BBmore data
CCsome more data row 2 ended

Обновить:

можно использовать: setLineSeparator("\nAA");?

1 ответ

Решение

Автор библиотеки здесь. Сначала вам нужно определить позиции поля. Поскольку вы хотите проанализировать значения, которые встречаются в нескольких строках, вы должны установить recordEndsOnNewLine в falseтак что вы на правильном пути.

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

String input = "" +
    "AA1234 data\nBBmore data\nCCsome more data row 1 ended\n" +
    "AA5678 data\nBBmore data\nCCsome more data row 2 ended";

Учитывая приведенный вами пример, можно создать следующую конфигурацию полей (я предположил, что вам не нужны строки "AA", "BB" и "CC"):

FixedWidthFields fields = new FixedWidthFields();
fields
        .addField("a1", 2, 6)
        .addField("a2", 7, 11)
        .addField("b1", 14, 23)
        .addField("c1", 26, 40)
        .addField("c2", 41, 52);

И вы можете проанализировать ваш вклад с этим:

FixedWidthParserSettings settings = new FixedWidthParserSettings(fields);
settings.getFormat().setLineSeparator("\n");
settings.setRecordEndsOnNewline(false);

FixedWidthParser parser = new FixedWidthParser(settings);

List<String[]> rows = parser.parseAll(new StringReader(input));
for (String[] row : rows) {
    System.out.println(Arrays.toString(row));
}

Это даст вам правильный вывод:

[1234, data, more data, some more data, row 1 ended]
[5678, data, more data, some more data, row 2 ended]

Теперь, когда мы знаем, где начинается и заканчивается каждое поле, мы можем определить ваш Java-бин:

public static class Bean {
    @FixedWidth(from = 2, to = 6)
    @Parsed
    int a1;

    @FixedWidth(from = 7, to = 11)
    @Parsed
    String a2;

    @FixedWidth(from = 14, to = 23)
    @Parsed
    String b1;

    @FixedWidth(from = 26, to = 40)
    @Parsed
    String c1;

    @FixedWidth(from = 41, to = 52)
    @Parsed
    String c2;

    @Override
    public String toString() {
        return "Bean{" +
                "a1=" + a1 +
                ", a2='" + a2 + '\'' +
                ", b1='" + b1 + '\'' +
                ", c1='" + c1 + '\'' +
                ", c2='" + c2 + '\'' +
                '}';
    }
}

Когда все готово, разбор ввода становится простым:

FixedWidthParserSettings settings = new FixedWidthParserSettings();
settings.getFormat().setLineSeparator("\n");
settings.setRecordEndsOnNewline(false);
settings.setHeaderExtractionEnabled(false); // This one is important as your input has no headers.

FixedWidthRoutines routines = new FixedWidthRoutines(settings);
for(Bean bean : routines.parseAll(Bean.class, new StringReader(input))){
    System.out.println(bean);
}

Который будет выводить бины на вывод так:

Bean{a1=1234, a2='data', b1='more data', c1='some more data', c2='row 1 ended'}
Bean{a1=5678, a2='data', b1='more data', c1='some more data', c2='row 2 ended'}

Надеюсь это поможет

Другие вопросы по тегам