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.util.StringUtil; 024import org.opengion.fukurou.util.FileUtil; 025import org.opengion.fukurou.util.Closer; // 6.2.0.0 (2015/02/27) 026import static org.opengion.fukurou.util.HybsConst.CR; 027import static org.opengion.fukurou.util.HybsConst.BUFFER_MIDDLE; 028 029/** 030 * 指定の区切り記号(初期値:タブ区切り)ファイルの読み取りクラスです。 031 * 032 * txt形式のテキストファイルを、イベント方式でテキストデータを読み取ります。 033 * タブ区切りテキストファイルで、セパレータと文字コードを外部から指定できます。 034 * 035 * @og.rev 6.2.0.0 (2015/02/27) 新規追加 036 * @og.group ファイル入力 037 * 038 * @version 6.0 039 * @author Kazuhiko Hasegawa 040 * @since JDK6.0, 041 */ 042public class EventReader_TEXT implements EventReader { 043 /** このプログラムのVERSION文字列を設定します。 {@value} */ 044 private static final String VERSION = "6.3.1.0 (2015/06/28)" ; 045 046 private String separator = "\t"; // 項目区切り文字 047 private String encode = "UTF-8"; // Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle・・・ 048 049 /** 050 * 引数ファイル(Text)を、イベントモデルを使用してテキスト化します。 051 * 052 * TableModelHelperは、EXCEL/TEXT読み取り処理用の統一されたイベント処理クラスです。 053 * openGion特有のEXCEL/TEXT処理方法(#NAME , 先頭行#コメントなど)を実装しています。 054 * これは、EXCELやTEXTの処理を、統一的なイベントモデルで扱うためです。 055 * あくまで、読み取り限定であれば、こちらのイベントモデルで十分です。 056 * 057 * @og.rev 6.2.0.0 (2015/02/27) 新規作成 058 * @og.rev 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 059 * 060 * @param file 入力ファイル 061 * @param helper イベント処理するオブジェクト 062 */ 063 @Override 064 public void eventReader( final File file , final TableModelHelper helper ) { 065 BufferedReader reader = null ; 066 067 try { 068 helper.startFile( file ); 069 070 // 6.2.0.0 (2015/02/27) TableModelHelper 変更に伴う修正 071 reader = FileUtil.getBufferedReader( file,encode ); 072 073 String line; 074 int rowNo = 0; 075 final char sepa = separator.charAt(0); 076 077 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 078 while((line = reader.readLine()) != null) { 079 if( helper.isSkip( rowNo ) ) { break; } 080 081 // 5.2.0.0 (2010/09/01) ""で囲われているデータに改行が入っていた場合の対応 082 int quotCount = StringUtil.countChar( line, '"' ); 083 if( quotCount % 2 != 0 ) { 084 String addLine = null; 085 buf.setLength(0); 086 buf.append( line ); 087 while(quotCount % 2 != 0 && (addLine = reader.readLine()) != null) { 088 buf.append( CR ).append( addLine ); 089 quotCount += StringUtil.countChar( addLine, '"' ); 090 } 091 line = buf.toString(); 092 } 093 helper.value( line, rowNo++, sepa ); 094 // オーバーフロー時は、HybsOverflowException が throw される。 095 // if( helper.isOverflow() ) { break; } // オーバーフローで打ち切り 096 } 097 } 098 // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 099 catch ( CharacterCodingException ex ) { 100 final String errMsg = "文字のエンコード・エラーが発生しました。" + CR 101 + " ファイルのエンコードが指定のエンコードと異なります。" + CR 102 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 103 throw new RuntimeException( errMsg,ex ); 104 } 105 catch ( IOException ex ) { 106 final String errMsg = "ファイル読込みエラーが発生しました。" + CR 107 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 108 throw new RuntimeException( errMsg,ex ); 109 } 110 finally { 111 Closer.ioClose( reader ); 112 helper.endFile( file ); // 6.2.0.0 (2015/02/27) 113 } 114 } 115 116 /** 117 * データを読み込む場合の,区切り文字をセットします。 118 * 119 * なお,このメソッドは,サブクラスによっては,使用しない場合があります。 120 * もし,使用しないサブクラスを作成する場合は, UnsupportedOperationException 121 * を throw するように,サブクラスで実装して下さい。 122 * 123 * @param sep 区切り文字 124 */ 125 public void setSeparator( final String sep ) { 126 if( sep != null ) { separator = sep; } 127 } 128 129 /** 130 * 読み取り元ファイルのエンコード文字列を指定します。 131 * ファイルは、BufferedReader で受け取る為、本来は、エンコードは不要ですが、 132 * 固定長ファイルの読み取り時のバイトコード分割時に、指定のエンコードで 133 * 分割する必要があります。(例えば、半角文字は、Shift_JIS では、1バイト) 134 * 135 * @param enc ファイルのエンコード文字列 136 */ 137 public void setEncode( final String enc ) { 138 encode = enc; 139 } 140}