public class VariableLengthDataRecordFormatter extends DataRecordFormatterSupport
本クラスはスレッドセーフを考慮した実装にはなっていないので、呼び出し元で同期化の制御を行うこと。
ディレクティブの設定可変長ファイルデータを読み込む際は、以下のディレクティブの設定が必須となる。
また、任意で以下の設定を行うことができる。
フィールド区切り文字および囲み文字は、任意の1文字を指定できる。
また、レコード終端文字列は、許容する文字列のみ指定できる。
デフォルトでは「\n」「\r」「\r\n」の3種類の文字列をレコード終端文字列として許容するが、
それを変更したい場合は、任意の許容する文字列のリストをFormatterFactory
クラスの allowedRecordSeparatorList プロパティに設定すること。
タイトル行の読み書き
requires-titleディレクティブにtrueを設定することで、タイトル行を読み書きする機能が有効となり、最初の行をタイトル行として通常のレコードタイプとは別に取り扱うことができるようになる。
この場合、最初の行はタイトル固定のレコードタイプ名[Title]で読み書きできるようになる。
(※ここでいうタイトルとは、ファイルの最初の行に存在し、個々のフィールドの論理名などが記載されるレコードのことを示す)
通常、タイトル行・データ行のような2つのレコードタイプが存在するファイルを読み込むためにはマルチフォーマットの定義を行う必要があるが、
タイトル行とデータ行に対してフォーマットの適用条件となるフィールドが存在しない場合、マルチフォーマットの定義では読み込むことができない。
しかし、本機能を使用すれば、最初の行はタイトル固有のレコードタイプが、最初の行以降はそれ以外のレコードタイプが適用されるので、
タイトル行とデータ行を識別するためのフィールドが存在しなくても、以下のとおりシングルフォーマットの定義で読み込むことができる。
requires-title: true # requires-titleがtrueの場合、最初の行をタイトルとして読み書きできる。 [Title] # タイトル固有のレコードタイプ。最初の行はこのレコードタイプで読み書きされる。 1 Kubun N 2 Name N 3 Publisher N 4 Authors N 5 Price N [DataRecord] # 最初の行以降の行はこのレコードタイプで読み書きされる。 1 Kubun X 2 Name N 3 Publisher N 4 Authors N 5 Price N
また、本機能を使用する場合、最初の行がタイトル行であることが保証されるので、ファイルレイアウトのバリデーションを省略できるといったメリットもある。
以上の点より、最初の行にタイトルが存在するファイルを読み込む場合は、本機能を使用することを推奨する。
最初の行をタイトルとして読み書きする場合、以下の制約が発生する。この制約を満たさない場合、例外がスローされるので注意すること。
タイトル固有のレコードタイプ名はデフォルトでは [Title] だが、title-record-type-name ディレクティブでタイトル固有のレコードタイプ名を個別に指定することも可能である。
Modifier and Type | Class and Description |
---|---|
static class |
VariableLengthDataRecordFormatter.VariableLengthDirective
可変長ファイルフォーマッタが共通的に使用するディレクティブの名前と値の型。(タイプセーフEnum)
以下に一覧を示す。
field-separator:String quoting-delimiter:String ignore-blank-lines:Boolean requires-title:Boolean max-record-length:Integer title-record-type-name:String |
DataRecordFormatterSupport.Directive
Constructor and Description |
---|
VariableLengthDataRecordFormatter()
デフォルトコンストラクタ。
デフォルトでは、VariableLengthConvertorSettingをコンバータとして使用する。
|
Modifier and Type | Method and Description |
---|---|
void |
close()
内部的に保持している各種リソースを開放する。
|
protected boolean |
consumeQuoteIfExists(java.io.Reader in,
char quote)
後続の記号が囲み文字であれば読み込む。
|
protected java.lang.String |
consumeSeparator(java.io.Reader in,
java.lang.Character fieldSeparator,
java.lang.String recordSeparator)
セパレータを読み込む。
セパレータが読み込めなければ実行時例外を送出する。
|
protected java.lang.Object |
convertToField(java.lang.String fieldStr,
FieldDefinition field)
読み込んだフィールド文字列をコンバータを用いてオブジェクトに変換し、返却する。
|
protected DataRecord |
convertToRecord(java.util.List<java.lang.String> fieldStrList,
RecordDefinition recordDef)
読み込んだ1レコード分の文字列を、コンバータを用いてオブジェクトに変換し、返却する。
|
protected java.util.Map<java.lang.String,DataRecordFormatterSupport.Directive> |
createDirectiveMap()
使用するディレクティブの名前とDirectiveのMapを生成する。
サブクラスで使用するディレクティブを追加する場合は、本メソッドをオーバーライドし、任意のディレクティブを追加すること。
|
protected boolean |
endsWithChar(java.lang.Character character,
java.lang.StringBuilder buff)
バッファの末尾が指定した1文字で終了しているのであれば、
その1文字をバッファから除去した上でtrueを返却する。
|
protected boolean |
endsWithString(java.lang.String str,
java.lang.StringBuilder buff)
バッファの末尾が指定した文字列で終了しているのであれば、
その文字列をバッファから除去した上でtrueを返却する。
|
protected VariableLengthConvertorSetting |
getConvertorSetting()
コンバータの設定情報保持クラスを取得する
|
boolean |
hasNext()
次に読み込む行の有無を判定する。
|
protected boolean |
hasNextIgnoreBlankLines()
次に読み込む行があるかどうかを返却する。
空行の存在を無視する設定の場合、ファイル末尾に空行が存在しても、次に読み込む行がないと判定する。 |
DataRecordFormatter |
initialize()
フォーマット定義情報保持クラスの初期化を行う。
初期化は本メソッドの1回目の実行時のみ行われ、2回目以降の実行時に初期化は行われない。
|
protected void |
initializeField(java.util.Map<java.lang.String,java.lang.Object> directive)
フィールドを初期化する。
DataRecordFormatterSupport では、ディレクティブに設定された以下の値をフィールドに設定する。
レコード終端文字列
文字エンコーディング
|
protected void |
initializeFieldDefinition()
フィールド定義クラスについて、以下の初期化処理を行う。
コンバータ設定
エンコーディング設定
差分定義が行われている場合は、親のフィールド定義情報を反映
レコード長、フィールド長の妥当性検証
|
protected void |
initializeReader()
フォーマット定義ファイルで指定されたエンコーディングで、可変長データを読み込むリーダを生成する。
|
protected void |
initializeWriter()
ライタを生成する。
|
DataRecord |
readRecord()
入力ストリームから1レコード分のデータを読み込み、データレコードを返却する。
入力ストリームが既に終端に達していた場合は
null を返却する。 |
protected java.util.List<java.lang.String> |
readRecordAsString()
入力ストリームから、1行分のレコードに存在するフィールドを、囲み文字などを取り除いた文字列のリストとして読み込む。
|
protected DataRecordFormatterSupport |
setDataTypeProperty(DataType<?,?> datatype)
空文字列を
null に変換するかどうかを各データタイプに設定する。 |
DataRecordFormatter |
setInputStream(java.io.InputStream stream)
入力ストリームを設定する。
|
DataRecordFormatter |
setOutputStream(java.io.OutputStream stream)
出力ストリームを設定する。
|
protected void |
validateDirectives(java.util.Map<java.lang.String,java.lang.Object> directive)
ディレクティブの内容の妥当性を検証する。
|
protected void |
validateFieldLength(java.util.List<java.lang.String> fields,
RecordDefinition recordDef)
1レコード分のフィールド数が正しいかどうか検証する。
|
protected void |
writeField(java.util.Map<java.lang.String,?> record,
FieldDefinition field)
コンバータによる変換を行ったフィールドの内容を、出力ストリームへ書き込む。
|
void |
writeRecord(java.util.Map<java.lang.String,?> record)
出力ストリームに1レコード分の内容を書き込む。
出力時に使用するデータレイアウト(レコードタイプ)は、
Map の内容をもとに自動的に判定される。
引数がDataRecord 型かつレコードタイプが指定されている場合、
フォーマット定義ファイルのレコードタイプ識別フィールド定義よりも、指定されたレコードタイプを優先して書き込みを行う。 |
protected void |
writeRecord(java.util.Map<java.lang.String,?> record,
RecordDefinition recordType)
1レコード分の内容を、出力ストリームへ書き込む。
|
void |
writeRecord(java.lang.String recordType,
java.util.Map<java.lang.String,?> record)
指定したデータレイアウト(レコードタイプ)で、出力ストリームに1レコード分の内容を書き込む。
|
addConvertorToField, addFormatAndRecordNumberTo, createCharacterReplacer, getDefaultEncoding, getDefinition, getFileType, getMimeType, getRecordNumber, getRecordSeparator, incrementRecordNumber, initializeClassifier, initializeDefinition, newInvalidDataFormatException, setAllowedRecordSeparatorList, setDefaultReplacementType, setDefinition, setFieldProperty, setRecordNumber, setValueConvertorProperty, validateDirectivesDataType, validatePosition, validateRecordLength
@Published(tag="architect") public VariableLengthDataRecordFormatter()
public DataRecordFormatter initialize()
initialize
in interface DataRecordFormatter
initialize
in class DataRecordFormatterSupport
protected java.util.Map<java.lang.String,DataRecordFormatterSupport.Directive> createDirectiveMap()
createDirectiveMap
in class DataRecordFormatterSupport
protected void validateDirectives(java.util.Map<java.lang.String,java.lang.Object> directive)
サブクラスで独自のディレクティブを使用する場合は、このメソッドをオーバーライドし、独自のディレクティブに対して妥当性検証を行うこと。
DataRecordFormatter
では以下の仕様を満たしているかどうかの検証を行う。
妥当性検証に失敗した場合は、SyntaxErrorException
がスローされる。
validateDirectives
in class DataRecordFormatterSupport
directive
- ディレクティブprotected void initializeField(java.util.Map<java.lang.String,java.lang.Object> directive)
DataRecordFormatterSupport
では、ディレクティブに設定された以下の値をフィールドに設定する。
VariableLengthDataRecordFormatter
では、ディレクティブまたはコンポーネント設定ファイルに設定された以下の値をフィールドに設定する。
initializeField
in class DataRecordFormatterSupport
directive
- ディレクティブprotected void initializeFieldDefinition()
VariableLengthDataRecordFormatter
では、上記処理に加え、フォーマット定義が以下の条件を満たしているかどうかの検証を行う。条件を満たしていない場合、SyntaxErrorException
をスローする。
initializeFieldDefinition
in class DataRecordFormatterSupport
public DataRecordFormatter setInputStream(java.io.InputStream stream)
stream
- 入力ストリームpublic DataRecordFormatter setOutputStream(java.io.OutputStream stream)
stream
- 出力ストリーム@Published(tag="architect") public DataRecord readRecord() throws java.io.IOException
null
を返却する。java.io.IOException
- 入力ストリームの読み込みに失敗した場合@Published(tag="architect") protected void validateFieldLength(java.util.List<java.lang.String> fields, RecordDefinition recordDef)
fields
- フィールドのリストrecordDef
- レコード定義情報保持クラスprotected void initializeReader()
@Published(tag="architect") protected DataRecord convertToRecord(java.util.List<java.lang.String> fieldStrList, RecordDefinition recordDef) throws java.io.IOException
fieldStrList
- 読み込んだフィールド文字列のリストrecordDef
- レコード定義情報保持クラスjava.io.IOException
- 読み込みに伴うIO処理で問題が発生した場合。protected java.lang.Object convertToField(java.lang.String fieldStr, FieldDefinition field)
fieldStr
- 読み込んだフィールド文字列field
- フィールド定義情報保持クラスpublic void writeRecord(java.util.Map<java.lang.String,?> record) throws java.io.IOException, InvalidDataFormatException
Map
の内容をもとに自動的に判定される。
引数がDataRecord
型かつレコードタイプが指定されている場合、
フォーマット定義ファイルのレコードタイプ識別フィールド定義よりも、指定されたレコードタイプを優先して書き込みを行う。record
- 出力するレコードの内容を格納したMapjava.io.IOException
- 出力ストリームの書き込みに失敗した場合InvalidDataFormatException
- 書き込むデータの内容がフォーマット定義に違反している場合protected void initializeWriter()
public void writeRecord(java.lang.String recordType, java.util.Map<java.lang.String,?> record) throws java.io.IOException
recordType
- レコードタイプrecord
- 出力するレコードの内容を格納したMapjava.io.IOException
- 出力ストリームの書き込みに失敗した場合protected void writeRecord(java.util.Map<java.lang.String,?> record, RecordDefinition recordType) throws java.io.IOException
record
- 出力するレコードの内容を格納したMaprecordType
- レコードタイプjava.io.IOException
- 書き込みに伴うIO処理で問題が発生した場合。protected void writeField(java.util.Map<java.lang.String,?> record, FieldDefinition field) throws java.io.IOException
record
- 出力するレコードの内容を格納したMapfield
- フィールド定義情報保持クラスjava.io.IOException
- 書き込みに伴うIO処理で問題が発生した場合@Published(tag="architect") protected java.util.List<java.lang.String> readRecordAsString() throws java.io.IOException
java.io.IOException
- 読み込みに伴うIO処理で問題が発生した場合。protected boolean consumeQuoteIfExists(java.io.Reader in, char quote) throws java.io.IOException
in
- 入力ストリームquote
- 囲み文字java.io.IOException
- IOエラーprotected java.lang.String consumeSeparator(java.io.Reader in, java.lang.Character fieldSeparator, java.lang.String recordSeparator) throws java.io.IOException
in
- 入力ストリームrecordSeparator
- レコード終端文字列fieldSeparator
- フィールド区切り文字java.io.IOException
- IOエラーprotected boolean endsWithString(java.lang.String str, java.lang.StringBuilder buff)
str
- 終了条件の文字列buff
- バッファprotected boolean endsWithChar(java.lang.Character character, java.lang.StringBuilder buff)
character
- 1文字buff
- バッファpublic boolean hasNext() throws java.io.IOException
true
java.io.IOException
- 入力ストリームの読み込みに失敗した場合@Published(tag="architect") protected boolean hasNextIgnoreBlankLines() throws java.io.IOException
java.io.IOException
- - IOエラーpublic void close()
setInputStream(java.io.InputStream)
メソッドおよびsetOutputStream(java.io.OutputStream)
メソッドで渡されたストリーム、
および内部でそれらをラップするReader
、Writer
のストリームをクローズする。protected VariableLengthConvertorSetting getConvertorSetting()
getConvertorSetting
in class DataRecordFormatterSupport
protected DataRecordFormatterSupport setDataTypeProperty(DataType<?,?> datatype)
null
に変換するかどうかを各データタイプに設定する。setDataTypeProperty
in class DataRecordFormatterSupport
datatype
- 対象のデータタイプ