8. 固定長のカラムの読み書き
固定長のカラムは、書き込み時は任意の長さになるよう空白などを詰め、読み込み時は書き込み時に詰めた空白などの文字を除去するとで実現しています。[v2.1+]
固定長のカラムを定義したい場合は、フィールドにアノテーション @CsvFixedSize [ JavaDoc ] を付与します。
このアノテーションは、 以下の変換用のアノテーションを合成したアノテーションになります。
8.1. 基本的な設定
@CsvFixedSize の属性を指定することで、細やかな設定ができます。
属性
sizeにて、固定長のサイズを指定します。属性
rightAlignで右寄せするかどうか指定します。trueのとき右寄せとなります。書き込み時に左側にパディング文字を詰め、読み見込み時に左側の文字をトリミングします。falseのとき左寄席で、デフォルト値となります。書き込み時に右側にパディング文字を詰め、読み見込み時に右側の文字をトリミングします。
属性
padCharで、パディングする文字を指定できます。デフォルトは半角空白です。
値には、半角以外の全角文字の指定可能です。
属性
choppedで、書き込み時に指定したサイズを超えている場合、切り出すか指定します。デフォルトは
trueで切り出しません。
1import com.github.mygreen.supercsv.annotation.CsvBean;
2import com.github.mygreen.supercsv.annotation.CsvColumn;
3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
4
5
6@CsvBean
7public class SampleFixedSizeCsv {
8
9 // 右詰めする
10 @CsvColumn(number=1)
11 @CsvFixedSize(size=5, rightAlign=true)
12 private int id;
13
14 // パディング文字を全角空白にする。
15 // 全角を入力する前提としたカラムと想定し、さらに @CsvFullChar で半角を全角に変換します。
16 @CsvColumn(number=2, label="氏名")
17 @CsvFixedSize(size=10, padChar=' ')
18 @CsvFullChar
19 private String name;
20
21 // パディング文字をアンダースコア(_)にする。
22 @CsvColumn(number=3, label="生年月日")
23 @CsvFixedSize(length=10, padChar='_')
24 @CsvDateTimeFormat(pattern="uuuu-MM-dd")
25 private LocalDate birthday;
26
27 // 文字サイズを超えている場合は、切り出す。
28 @CsvColumn(number=4, label="備考")
29 @CsvFixedSize(size=20, chopped=true)
30 private String comment;
31
32 // getter, setterは省略
33}
8.2. 区切り文字のない固定長の処理
区切り文字のないCSVを処理する場合は、FixedSizeCsvPreference [ JavaDoc ] を使用し、CsvReader/CsvWriterを作成し処理します。 [v2.5+]
全てのカラムに
@CsvFixedSizeを付与する必要があります。区切り文字のない固定長カラム読み込むには、
FixedSizeCsvAnnotationBeanReader[ JavaDoc ] を使用します。区切り文字のない固定長カラムを書き込むには、
FixedSizeCsvAnnotationBeanWriter[ JavaDoc ] を使用します。
1 id氏名 生年月日______備考 ⏎
2 1山田 太郎 1980-01-28全ての項目に値が設定。 ⏎
3 2田中 次郎 __________誕生日の項目が空。 ⏎
4 3鈴木 三郎 2000-03-25 ⏎
1import java.io.IOException;
2
3import com.github.mygreen.supercsv.annotation.CsvBean;
4import com.github.mygreen.supercsv.annotation.CsvColumn;
5import com.github.mygreen.supercsv.annotation.CsvFixedSize;
6import com.github.mygreen.supercsv.io.FixedSizeCsvAnnotationBeanReader;
7import com.github.mygreen.supercsv.io.FixedSizeCsvPreference;
8
9public void testFixedSizeRead() throws IOException {
10
11 // FixedSizeCsvPreferenceの作成
12 FixedSizeCsvPreference<SampleFixedSizeCsv> csvPreference = FixedSizeCsvPreference.builder(SampleFixedSizeCsv.class)
13 .build();
14
15 // CsvReaderの作成
16 FixedSizeCsvAnnotationBeanReader<SampleFixedSizeCsv> csvReader = csvPreference.csvReader(
17 Files.newBufferedReader(Paths.get("sample_fixed_size.csv"), Charset.forName("UTF-8")));
18
19 try {
20 // 全行の取得
21 List<SampleFixedSizeCsv> list = csvReader.readAll();
22
23 } catch(SuperCsvException e) {
24 e.printStackTrace();
25 } finally {
26 csvReader.close();
27 }
28}
1import java.io.IOException;
2
3import com.github.mygreen.supercsv.annotation.CsvBean;
4import com.github.mygreen.supercsv.annotation.CsvColumn;
5import com.github.mygreen.supercsv.annotation.CsvFixedSize;
6import com.github.mygreen.supercsv.io.FixedSizeCsvAnnotationBeanWriter;
7import com.github.mygreen.supercsv.io.FixedSizeCsvPreference;
8
9public void testFixedSizeWrite() throws IOException {
10
11 // FixedSizeCsvPreferenceの作成
12 FixedSizeCsvPreference<SampleFixedSizeCsv> csvPreference = FixedSizeCsvPreference.builder(SampleFixedSizeCsv.class)
13 .build();
14
15 // CsvWriterの作成
16 FixedSizeCsvAnnotationBeanWriter<SampleFixedColumnBean> csvWriter = csvPrefrerence.csvWriter(
17 Files.newBufferedWriter(Paths.get("sample_fixed_size.csv"), Charset.forName("UTF-8")));
18
19 // 書き込みデータを作成
20 List<SampleFixedColumnBean> list = new ArrayList<>();
21 list.add(...);
22
23 try {
24 // 全行の書き込み
25 csvWriter.writeAll(list);
26 } catch (SuperCsvException e) {
27 e.printStackTrace();
28 } finally {
29 csvWriter.close();
30 }
31}
8.3. 区切り文字のある固定長の処理
区切り文字のある固定長CSVを処理する場合は、固定長としたいカラムにのみ @CsvFixedSize を付与し、通常のCsvAnnotationBeanReader / CsvAnnotationBeanWriter を使用します。
1 id,氏名 ,生年月日______,備考 ⏎
2 1,山田 太郎 ,1980-01-28,全ての項目に値が設定。 ⏎
3 2,田中 次郎 ,__________,誕生日の項目が空。 ⏎
4 3,鈴木 三郎 ,2000-03-25, ⏎
1import java.io.IOException;
2
3import com.github.mygreen.supercsv.annotation.CsvBean;
4import com.github.mygreen.supercsv.annotation.CsvColumn;
5import com.github.mygreen.supercsv.annotation.CsvFixedSize;
6import com.github.mygreen.supercsv.io.FixedSizeCsvAnnotationBeanReader;
7import com.github.mygreen.supercsv.io.FixedSizeCsvPreference;
8
9public void testFixedSizeRead2() throws IOException {
10
11 // CsvReaderの作成
12 CsvAnnotationBeanReader<SampleFixedSizeCsv> csvWriter = new CsvAnnotationBeanReader<>(
13 SampleFixedSizeCsv.class,
14 Files.newBufferedReader(Paths.get("sample_fixed_size.csv"), Charset.forName("UTF-8")),
15 CsvPreference.STANDARD_PREFERENCE);
16
17 try {
18 // 全行の取得
19 List<SampleFixedSizeCsv> list = csvReader.readAll();
20
21 } catch(SuperCsvException e) {
22 e.printStackTrace();
23 } finally {
24 csvReader.close();
25 }
26}
1import java.io.IOException;
2
3import com.github.mygreen.supercsv.annotation.CsvBean;
4import com.github.mygreen.supercsv.annotation.CsvColumn;
5import com.github.mygreen.supercsv.annotation.CsvFixedSize;
6import com.github.mygreen.supercsv.io.FixedSizeCsvAnnotationBeanWriter;
7import com.github.mygreen.supercsv.io.FixedSizeCsvPreference;
8
9public void testFixedSizeWrite2() throws IOException {
10
11 // CsvReaderの作成
12 CsvAnnotationBeanWriter<SampleFixedSizeCsv> csvWriter = new CsvAnnotationBeanWriter<>(
13 SampleFixedSizeCsv.class,
14 Files.newBufferedWriter(Paths.get("sample_fixed_size.csv"), Charset.forName("UTF-8")),
15 CsvPreference.STANDARD_PREFERENCE);
16
17 // 書き込みデータを作成
18 List<SampleFixedColumnBean> list = new ArrayList<>();
19 list.add(...);
20
21 try {
22 // 全行の書き込み
23 csvWriter.writeAll(list);
24 } catch (SuperCsvException e) {
25 e.printStackTrace();
26 } finally {
27 csvWriter.close();
28 }
29}
出力されるCSVは下記のようになります。
ヘッダー行が固定長になっていないことがわかります。
1id,氏名,生年月日,備考
2 1,山田 太郎 ,1990-01-12,コメント
3 2,山田 花子 ,__________,
ヘッダー行もカラムの定義と同様に固定長にしたい場合は、@CsvBean(headerMapper=<ヘッダーのマッピング処理クラス>) でヘッダーの処理方法を変更します。
FixedSizeHeaderMapper [ JavaDoc ] は、フィールドに付与されたアノテーション @CsvFixedSize を元に、見出しに対してパディングを行います。
1import com.github.mygreen.supercsv.annotation.CsvBean;
2import com.github.mygreen.supercsv.annotation.CsvColumn;
3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
4import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper;
5
6@CsvBean(header=true, headerMapper=FixedSizeHeaderMapper.class)
7public class SampleFixedSizeCsv {
8
9 // 右詰めする
10 @CsvColumn(number=1)
11 @CsvFixedSize(size=10, rightAlign=true)
12 private int id;
13
14 // 以下、省略
15}
1 id,氏名 ,生年月日__,備考
2 1,山田 太郎 ,1990-01-12,コメント
3 2,山田 花子 ,__________,
注釈
ヘッダーの見出しが全角、実際の値が半角で出力するような場合、意図した変換がされない場合があります。
その際は、独自に com.github.mygreen.supercsv.builder.HeaderMapper を実装したクラスを指定することで対応できます。
8.4. パディング処理方式の切り替え
固定長としてパディングする場合、サイズカウント方法の考え方は、複数あります。 例えば、半角は1文字、全角は2文字分として換算する。 または、文字のバイト数で換算することもあります。
パディング処理の実装を切り替えることができ、
@CsvFixedSizeの属性paddingProcessorでパディング処理の実装クラスを指定します。本ライブラリでは、以下のパディング処理の実装が提供されています。
独自のパディング処理を指定したい場合は、
com.github.mygreen.supercsv.cellprocessor.conversion.PaddingProcessorを実装したクラスを指定してください。
1import com.github.mygreen.supercsv.annotation.CsvBean;
2import com.github.mygreen.supercsv.annotation.CsvColumn;
3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
4import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper;
5import com.github.mygreen.supercsv.cellprocessor.conversion.ByteSizePaddingProcessor;
6import com.github.mygreen.supercsv.cellprocessor.conversion.CharWidthPaddingProcessor;
7import com.github.mygreen.supercsv.cellprocessor.conversion.SimplePaddingProcessor;
8
9@CsvBean(header=true)
10public class SampleFixedSizeCsv {
11
12 // 文字の種別にかかわらず1文字としてカウントしてパディングします。
13 @CsvColumn(number=1)
14 @CsvFixedSize(size=10, paddingProcessor=SimplePaddingProcessor.class)
15 private int id;
16
17 // 文字の幅(半角は1文字、全角は2文字)によってカウントしてパディングします。
18 @CsvColumn(number=2)
19 @CsvFixedSize(size=20, paddingProcessor=CharWidthPaddingProcessor.class)
20 private String name;
21
22 // バイト数によってカウントしてパディングします。
23 @CsvColumn(number=3)
24 @CsvFixedSize(size=20, paddingProcessor=ByteSizePaddingProcessor.Windows31j.class)
25 private String comment;
26
27 // 以下、省略
28}