Рубрики
Без рубрики

Парсеры однозначности

Изучите основы синтаксического анализа файлов с помощью библиотеки Univocity.

Автор оригинала: Amy DeGregorio.

1. введение

В этом уроке мы быстро рассмотрим Univocity Parsers , библиотеку для анализа файлов CSV, TSV и файлов фиксированной ширины в Java.

Мы начнем с основ чтения и записи файлов, прежде чем перейдем к чтению и записи файлов в Java-компоненты и из них. Затем мы быстро рассмотрим параметры конфигурации, прежде чем завершить работу.

2. Настройка

Чтобы использовать парсеры, нам нужно добавить последнюю зависимость Maven в ваш проект pom.xml файл:


    com.univocity
    univocity-parsers
    2.8.4

3. Основное использование

3.1. Чтение

В Univocity мы можем быстро проанализировать весь файл в коллекцию массивов String , которые представляют каждую строку в файле.

Во-первых, давайте проанализируем CSV-файл, предоставив Reader нашему CSV-файлу в CsvParser с настройками по умолчанию:

try (Reader inputReader = new InputStreamReader(new FileInputStream(
  new File("src/test/resources/productList.csv")), "UTF-8")) {
    CsvParser parser = new CsvParser(new CsvParserSettings());
    List parsedRows = parser.parseAll(inputReader);
    return parsedRows;
} catch (IOException e) {
    // handle exception
}

Мы можем легко переключить эту логику для анализа CSV-файла, переключившись на TsvParser и предоставив ему файл TSV.

Обработка файла фиксированной ширины лишь немного сложнее. Основное различие заключается в том, что нам нужно указать ширину полей в настройках парсера.

Давайте прочитаем файл фиксированной ширины, предоставив Поля фиксированной ширины объект для наших Настроек FixedWidthParser :

try (Reader inputReader = new InputStreamReader(new FileInputStream(
  new File("src/test/resources/productList.txt")), "UTF-8")) {
    FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
    FixedWidthParserSettings settings = new FixedWidthParserSettings(fieldLengths);

    FixedWidthParser parser = new FixedWidthParser(settings);
    List parsedRows = parser.parseAll(inputReader);
    return parsedRows;
} catch (IOException e) {
    // handle exception
}

3.2. Письменность

Теперь, когда мы рассмотрели чтение файлов с помощью парсеров, давайте научимся их писать.

Запись файлов очень похожа на их чтение в том, что мы предоставляем Writer вместе с нашими желаемыми настройками парсеру, который соответствует нашему типу файла.

Давайте создадим метод для записи файлов во всех трех возможных форматах:

public boolean writeData(List products, OutputType outputType, String outputPath) {
    try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)),"UTF-8")){
        switch(outputType) {
            case CSV:
                CsvWriter writer = new CsvWriter(outputWriter, new CsvWriterSettings());
                writer.writeRowsAndClose(products);
                break;
            case TSV:
                TsvWriter writer = new TsvWriter(outputWriter, new TsvWriterSettings());
                writer.writeRowsAndClose(products);
                break;
            case FIXED_WIDTH:
                FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
                FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths);
                FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings);
                writer.writeRowsAndClose(products);
                break;
            default:
                logger.warn("Invalid OutputType: " + outputType);
                return false;
        }
        return true;
    } catch (IOException e) {
        // handle exception
    }
}

Как и в случае чтения файлов, запись CSV-файлов и TSV-файлов почти идентична. Для файлов фиксированной ширины мы должны указать ширину поля в наших настройках.

3.3. Использование процессоров Строк

Univocity предоставляет ряд процессоров строк, которые мы можем использовать, а также предоставляет нам возможность создавать свои собственные.

Чтобы получить представление об использовании необработанных процессоров, давайте использовать процессор пакетных столбцов для обработки большего CSV-файла в пакетах из пяти строк:

try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) {
    CsvParserSettings settings = new CsvParserSettings();
    settings.setProcessor(new BatchedColumnProcessor(5) {
        @Override
        public void batchProcessed(int rowsInThisBatch) {}
    });
    CsvParser parser = new CsvParser(settings);
    List parsedRows = parser.parseAll(inputReader);
    return parsedRows;
} catch (IOException e) {
    // handle exception
}

Чтобы использовать этот необработанный процессор, мы определяем его в наших CsvParserSettings , а затем все, что нам нужно сделать, это вызвать разобрать все .

3.4. Чтение и запись в Java-компоненты

Список массивов String в порядке, но мы часто работаем с данными в Java-компонентах. Univocity также позволяет читать и записывать в специально аннотированные Java-компоненты.

Давайте определим Product bean с аннотациями Univocity:

public class Product {

    @Parsed(field = "product_no")
    private String productNumber;
    
    @Parsed
    private String description;
    
    @Parsed(field = "unit_price")
    private float unitPrice;

    // getters and setters
}

Основной аннотацией является @Разобран аннотация.

Если заголовок нашего столбца совпадает с именем поля, мы можем использовать @Parsed без каких-либо указанных значений. Если заголовок столбца отличается от имени поля, мы можем указать заголовок столбца с помощью свойства field .

Теперь, когда мы определили наш Продукт bean, давайте прочитаем в него наш CSV-файл:

try (Reader inputReader = new InputStreamReader(new FileInputStream(
  new File("src/test/resources/productList.csv")), "UTF-8")) {
    BeanListProcessor rowProcessor = new BeanListProcessor(Product.class);
    CsvParserSettings settings = new CsvParserSettings();
    settings.setHeaderExtractionEnabled(true);
    settings.setProcessor(rowProcessor);
    CsvParser parser = new CsvParser(settings);
    parser.parse(inputReader);
    return rowProcessor.getBeans();
} catch (IOException e) {
    // handle exception
}

Сначала мы создали специальный процессор строк, BeanListProcessor, с нашим аннотированным классом. Затем мы предоставили это в CsvParserSettings и использовали его для чтения в списке Product s.

Далее, давайте запишем наш список Product s в файл фиксированной ширины:

try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)), "UTF-8")) {
    BeanWriterProcessor rowProcessor = new BeanWriterProcessor(Product.class);
    FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
    FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths);
    settings.setHeaders("product_no", "description", "unit_price");
    settings.setRowWriterProcessor(rowProcessor);
    FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings);
    writer.writeHeaders();
    for (Product product : products) {
        writer.processRecord(product);
    }
    writer.close();
    return true;
} catch (IOException e) {
    // handle exception
}

Заметная разница заключается в том, что мы указываем заголовки столбцов в наших настройках.

4. Настройки

Univocity имеет ряд настроек, которые мы можем применить к парсерам. Как мы видели ранее, мы можем использовать настройки для применения процессора строк к анализаторам.

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

Давайте скорректируем настройки нашего парсера CSV, чтобы установить некоторые ограничения на данные, которые мы читаем:

CsvParserSettings settings = new CsvParserSettings();
settings.setMaxCharsPerColumn(100);
settings.setMaxColumns(50);
CsvParser parser = new CsvParser(new CsvParserSettings());

5. Заключение

В этом кратком руководстве мы изучили основы синтаксического анализа файлов с помощью библиотеки Univocity.

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

Как всегда, исходный код доступен на GitHub .