001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.model; 017 018import java.io.BufferedReader; 019import java.io.File; 020import java.io.IOException; 021import java.nio.charset.CharacterCodingException; // 6.3.1.0 (2015/06/28) 022 023import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 024import org.opengion.fukurou.system.OgCharacterException ; // 6.5.0.1 (2016/10/21) 025import org.opengion.fukurou.util.StringUtil; 026import org.opengion.fukurou.util.FileUtil; 027import org.opengion.fukurou.system.Closer; // 6.2.0.0 (2015/02/27) 028import static org.opengion.fukurou.system.HybsConst.CR; 029import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; 030 031/** 032 * 指定の区切り記号(初期値:タブ区切り)ファイルの読み取りクラスです。 033 * 034 * txt形式のテキストファイルを、イベント方式でテキストデータを読み取ります。 035 * タブ区切りテキストファイルで、セパレータと文字コードを外部から指定できます。 036 * 037 * @og.rev 6.2.0.0 (2015/02/27) 新規追加 038 * @og.group ファイル入力 039 * 040 * @version 6.0 041 * @author Kazuhiko Hasegawa 042 * @since JDK6.0, 043 */ 044public class EventReader_TEXT implements EventReader { 045 /** このプログラムのVERSION文字列を設定します。 {@value} */ 046 private static final String VERSION = "6.5.0.1 (2016/10/21)" ; 047 048 private String separator = "\t"; // 項目区切り文字 049 private String encode = "UTF-8"; // Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle・・・ 050 051 /** 052 * デフォルトコンストラクター 053 * 054 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 055 */ 056 public EventReader_TEXT() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 057 058 /** 059 * 引数ファイル(Text)を、イベントモデルを使用してテキスト化します。 060 * 061 * TableModelHelperは、EXCEL/TEXT読み取り処理用の統一されたイベント処理クラスです。 062 * openGion特有のEXCEL/TEXT処理方法(#NAME , 先頭行#コメントなど)を実装しています。 063 * これは、EXCELやTEXTの処理を、統一的なイベントモデルで扱うためです。 064 * あくまで、読み取り限定であれば、こちらのイベントモデルで十分です。 065 * 066 * @og.rev 6.2.0.0 (2015/02/27) 新規作成 067 * @og.rev 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 068 * @og.rev 6.5.0.1 (2016/10/21) CharacterCodingException は、OgCharacterException に変換する。 069 * 070 * @param file 入力ファイル 071 * @param helper イベント処理するオブジェクト 072 */ 073 @Override // EventReader 074 public void eventReader( final File file , final TableModelHelper helper ) { 075 BufferedReader reader = null ; 076 077 try { 078 helper.startFile( file ); 079 080 // 6.2.0.0 (2015/02/27) TableModelHelper 変更に伴う修正 081 reader = FileUtil.getBufferedReader( file,encode ); 082 083 String line; 084 int rowNo = 0; 085 final char sepa = separator.charAt(0); 086 087 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 088 while((line = reader.readLine()) != null) { 089 if( helper.isSkip( rowNo ) ) { break; } 090 091 // 5.2.0.0 (2010/09/01) ""で囲われているデータに改行が入っていた場合の対応 092 int quotCount = StringUtil.countChar( line, '"' ); 093 if( quotCount % 2 != 0 ) { 094 String addLine = null; 095 buf.setLength(0); 096 buf.append( line ); 097 while(quotCount % 2 != 0 && (addLine = reader.readLine()) != null) { 098 buf.append( CR ).append( addLine ); 099 quotCount += StringUtil.countChar( addLine, '"' ); 100 } 101 line = buf.toString(); 102 } 103 helper.value( line, rowNo++, sepa ); 104 // // オーバーフロー時は、HybsOverflowException が throw される。 105 // if( helper.isOverflow() ) { break; } // オーバーフローで打ち切り 106 } 107 } 108 // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 109 catch( final CharacterCodingException ex ) { 110 final String errMsg = "文字のエンコード・エラーが発生しました。" + CR 111 + " ファイルのエンコードが指定のエンコードと異なります。" + CR 112 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 113 throw new OgCharacterException( errMsg,ex ); // 6.5.0.1 (2016/10/21) 114 } 115 catch( final IOException ex ) { 116 final String errMsg = "ファイル読込みエラーが発生しました。" + CR 117 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 118 throw new OgRuntimeException( errMsg,ex ); 119 } 120 finally { 121 Closer.ioClose( reader ); 122 helper.endFile( file ); // 6.2.0.0 (2015/02/27) 123 } 124 } 125 126 /** 127 * データを読み込む場合の区切り文字をセットします。 128 * 129 * なお、このメソッドは、サブクラスによっては使用しない場合があります。 130 * もし、使用しないサブクラスを作成する場合は、UnsupportedOperationException 131 * を throw するようにサブクラスで実装して下さい。 132 * 133 * @param sep 区切り文字 134 */ 135 public void setSeparator( final String sep ) { 136 if( sep != null ) { separator = sep; } 137 } 138 139 /** 140 * 読み取り元ファイルのエンコード文字列を指定します。 141 * ファイルは、BufferedReader で受け取る為、本来は、エンコードは不要ですが、 142 * 固定長ファイルの読み取り時のバイトコード分割時に、指定のエンコードで 143 * 分割する必要があります。(例えば、半角文字は、Shift_JIS では、1バイト) 144 * 145 * @param enc ファイルのエンコード文字列 146 */ 147 public void setEncode( final String enc ) { 148 encode = enc; 149 } 150}