1. 序章

このチュートリアルでは、 Univocity Parsers を簡単に見ていきます。これは、JavaのCSV、TSV、および固定幅ファイルを解析するためのライブラリです。

Java Beanとの間でファイルを読み書きする前に、ファイルの読み取りと書き込みの基本から始めます。 次に、まとめる前に、構成オプションについて簡単に説明します。

2. 設定

パーサーを使用するには、最新のMaven依存関係をプロジェクトpom.xmlファイルに追加する必要があります。

<dependency>
    <groupId>com.univocity</groupId>
    <artifactId>univocity-parsers</artifactId>
    <version>2.8.4</version>
</dependency>

3. 基本的な使用法

3.1. 読む

Univocityでは、ファイル全体をすばやく解析して、ファイルの各行を表すString配列のコレクションにすることができます。

まず、CSVファイルに Readerをデフォルト設定のCsvParserに提供して、CSVファイルを解析しましょう。

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

TsvParser に切り替えてTSVファイルを提供することで、このロジックを簡単に切り替えてTSVファイルを解析できます。

固定幅のファイルを処理するのは少しだけ複雑です。 主な違いは、パーサー設定でフィールド幅を指定する必要があることです。

FixedWidthFieldsオブジェクトをFixedWidthParserSettingsに提供して、固定幅ファイルを読み取ってみましょう。

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<String[]> parsedRows = parser.parseAll(inputReader);
    return parsedRows;
} catch (IOException e) {
    // handle exception
}

3.2. 書き込み

パーサーを使用したファイルの読み取りについて説明したので、ファイルの記述方法を学びましょう。

ファイルの書き込みは、ファイルタイプに一致するパーサーに Writer と必要な設定を提供するという点で、ファイルの読み取りと非常によく似ています。

3つの可能な形式すべてでファイルを書き込むメソッドを作成しましょう。

public boolean writeData(List<Object[]> 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は、使用できる多数の行プロセッサーを提供し、独自の行プロセッサーを作成する機能も提供します。

行プロセッサの使用感をつかむために、 BatchedColumnProcessor を使用して、より大きなCSVファイルを5行のバッチで処理してみましょう。

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<String[]> parsedRows = parser.parseAll(inputReader);
    return parsedRows;
} catch (IOException e) {
    // handle exception
}

この行プロセッサを使用するには、 CsvParserSettings で定義し、parseAllを呼び出すだけです。

3.4. JavaBeansへの読み取りと書き込み

String 配列のリストは問題ありませんが、JavaBeanのデータを処理することがよくあります。 Univocityでは、特別に注釈が付けられたJavaBeanの読み取りと書き込みも可能です。

Univocityアノテーションを使用してProductbeanを定義しましょう。

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アノテーションです。

列見出しがフィールド名と一致する場合は、値を指定せずに@Parsedを使用できます。 列見出しがフィールド名と異なる場合は、fieldプロパティを使用して列見出しを指定できます。

Product beanを定義したので、CSVファイルを読み込みます。

try (Reader inputReader = new InputStreamReader(new FileInputStream(
  new File("src/test/resources/productList.csv")), "UTF-8")) {
    BeanListProcessor<Product> rowProcessor = new BeanListProcessor<Product>(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のリストを読み込みました。

次に、Productのリストを固定幅のファイルに書き込みます。

try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)), "UTF-8")) {
    BeanWriterProcessor<Product> rowProcessor = new BeanWriterProcessor<Product>(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には、パーサーに適用できる設定がいくつかあります。 前に見たように、設定を使用して行プロセッサーをパーサーに適用できます。

ニーズに合わせて変更できる設定は他にもたくさんあります。 構成の多くは3つのファイルタイプに共通ですが、各パーサーにはフォーマット固有の設定もあります。

CSVパーサーの設定を調整して、読み取るデータにいくつかの制限を設けましょう。

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

5. 結論

このクイックチュートリアルでは、Univocatyライブラリを使用したファイルの解析の基本を学びました。

文字列配列とJavaBeanの両方のリストでファイルを読み書きする方法を学びました。 以前、Java Beanに入る前に、さまざまな行プロセッサの使用について簡単に説明しました。 最後に、設定をカスタマイズする方法について簡単に触れました。

いつものように、ソースコードはGitHubから入手できます。