BeanIOとは
ApacheのJavaライブラリ。CSV・固定長データ・XMLなどをJavaクラスにマッピングできる。
ここ数年更新されておらず、日本語の記事も皆無なので、このライブラリを使うのがベストなのか分からないけど、特定の場面では有効かなと思います。
リファレンス(英語)はこちら。
http://beanio.org/2.1/docs/reference/index.html#FixedLengthStreamFormat
英語読める人はリファレンス読めばいいけど、所どころサンプルコードに間違いがあったので注意して下さい。
導入
Mavenの場合。
<dependency>
<groupId>org.beanio</groupId>
<artifactId>beanio</artifactId>
<version>2.1.0</version>
</dependency>
zipはこちら。
https://code.google.com/archive/p/beanio/downloads
CSV→オブジェクト
手始めにCSV→オブジェクトのマッピングをしてみる。
まず、CSVファイルと、CSVの各項目に対応するフィールドを持つクラスを作成する。
CSVファイル
Joe,Smith,11000000,20091001,Developer
Jane,Doe,12000000,20080115,Architect
Jon,Anderson,6000000,20100318,Manager
マッピングするクラス
package example;
import java.util.Date;
public class Employee {
String firstName;
String lastName;
int salary;
Date hireDate;
String title;
// 省略しているが、getter,setterも必要
}
で、CSVとクラスのマッピング定義を作成する。
マッピング定義
<beanio xmlns="http://www.beanio.org/2012/03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">
<stream name="employeeFile" format="csv" >
<parser>
<property name="delimiter" value="," />
</parser>
<record name="employee" class="example.Employee" >
<field name="firstName" />
<field name="lastName" />
<field name="salary" />
<field name="hireDate" format="yyyyMMdd" />
<field name="title" />
</record>
</stream>
</beanio>
fieldの定義順が対象データの順番と対応している。
デフォルトで区切り文字がカンマなので、この場合parserタグは無くてもいい。
区切り文字を変えたい場合はvalueの値を変更して下さい。
これで準備OK。実際の変換処理を書いてみる。
package example;
import org.beanio.BeanReader;
import org.beanio.StreamFactory;
import java.io.File;
public class BeanReaderExample {
public static void main(String[] args) {
// マッピング定義を指定して、ファクトリを生成
StreamFactory factory = StreamFactory.newInstance();
factory.load("src/main/resources/mapping.xml");
// ファクトリからBeanReaderを生成
// 第1引数にマッピング定義のstream名を指定する
BeanReader reader = factory.createReader("employeeFile", new File("src/main/resources/employee.dat"));
// BeanReaderを使ってCSVの内容をオブジェクトにセット
Employee employee;
while ((employee = (Employee) reader.read()) != null) {
System.out.println("FirstName : " + employee.getFirstName());
System.out.println("LastName : " + employee.getLastName());
System.out.println("Salary : " + employee.getSalary());
System.out.println("HireDate : " + employee.getHireDate());
System.out.println("Title : " + employee.getTitle());
System.out.println();
}
reader.close();
}
}
実行すると、出力結果は以下のようになる。
FirstName : Joe
LastName : Smith
Salary : 11000000
HireDate : Thu Oct 01 00:00:00 JST 2009
Title : Developer
FirstName : Jane
LastName : Doe
Salary : 12000000
HireDate : Tue Jan 15 00:00:00 JST 2008
Title : Architect
FirstName : Jon
LastName : Anderson
Salary : 6000000
HireDate : Thu Mar 18 00:00:00 JST 2010
Title : Manager
マッピングできてますね。
固定長データ→オブジェクト
固定長データ
Joe Smith 01100000020091001Developer
Jane Doe 01200000020080115Architect
Jon Anderson 00600000020100318Manager
データ長の定義は、
名前=10桁, 姓=10桁, 年収=9桁, 雇用日=8桁, 肩書き=可変長
としています。
固定長と言いつつ、末尾だけは可変長です。
マッピングするクラス(Employee.java)はCSVの時と同じ。
マッピング定義は固定長用に変更する必要があります。
マッピング定義
<beanio xmlns="http://www.beanio.org/2012/03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">
<stream name="employeeFile" format="fixedlength" >
<record name="employee" class="example.Employee" >
<field name="firstName" length="10" />
<field name="lastName" length="10" />
<field name="salary" length="9" />
<field name="hireDate" length="8" format="yyyyMMdd" />
<field name="title" length="unbounded" />
</record>
</stream>
</beanio>
streamタグのformatを"csv"から"fixedlength"に変更し、fieldタグにlengthを追加。
末尾のみ可変長にできるので、"unbounded"を指定しています。
実際の変換処理(BeanReaderExample.java)と出力結果はCSVの時と同じ。
その他
今回はCSV、固定長データ→オブジェクトへのマッピングのみでしたが、XMLのマッピングも当然可能です。
ただ、XMLについてはJAXBとかあるし、BeanIO使う利点が分かっていないので、扱っていません。
また、オブジェクト→CSV等への変換も可能です。気が向いたら後日まとめるかも。