    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.util;
    017
    018import java.io.FileInputStream;
    019import java.io.UnsupportedEncodingException;
    020import java.io.IOException;
    021import java.util.StringTokenizer;
    022
    023/**
    024 * FileString は、ファイルを読み取って、そのまま String 文字列として返すクラスです。
    025 * SQLを記述したファイルや、コマンドを記述したファイルを読み取って、コマンドラインからの
    026 * 入力として利用できます。
    027 *
    028 * ファイルは、一旦すべて読み取ってメモリ上で加工されます。
    029 * パラメータ等の設定ファイルをイメージしている為、巨大なファイルの読み込みは出来ません。
    030 *
    031 * @version  4.0
    032 * @author   Kazuhiko Hasegawa
    033 * @since    JDK5.0,
    034 */
    035public class FileString  {
    036        private String  filename        = null ;
    037        private String  encode          = null ;
    038        private String  value           = null ;
    039
    040        /**
    041         * ファイル名を設定します。
    042         * 指定のファイルを読み取って、内部文字列に格納します。
    043         * なお、格納するタイミングは、#getValue() を最初に行ったときです。
    044         * ファイル名を再設定すると、内部のvalue は、クリアされます。
    045         *
    046         * @param  filename ファイル名
    047         */
    048        public void setFilename( final String filename ) {
    049                if( filename == null ) {
    050                        String errMsg = "ファイル名が指定されていません。" ;
    051                        throw new RuntimeException( errMsg );
    052                }
    053
    054                this.filename = filename;
    055                value             = null;               // 初期化
    056        }
    057
    058        /**
    059         * ファイル名を取得します。
    060         *
    061         * @og.rev 5.2.3.0 (2010/12/01) 新規追加
    062         *
    063         * @return      ファイル名
    064         */
    065        public String getFilename() {
    066                return filename;
    067        }
    068
    069        /**
    070         * ファイルのエンコードを設定します。
    071         * 指定のファイルを読み取る場合のエンコードを指定します。
    072         * 正確には、バイナリデータを読み取って、文字列に変換する場合に、
    073         * String( byte[],String ) コンストラクタの引数に使用します。
    074         * 指定されていない場合は、String( byte[] ) コンストラクタで変換します。
    075         * エンコードを再設定すると、内部のvalue は、クリアされます。
    076         *
    077         * @param  encode エンコード名
    078         */
    079        public void setEncode( final String encode ) {
    080                this.encode     = encode;
    081                value           = null;         // 初期化
    082        }
    083
    084        /**
    085         * ファイルのエンコードを取得します。
    086         * 正確には、内部文字列に変換したときのエンコードです。
    087         * null の場合は、無指定(つまりデフォルトエンコード)と
    088         * なります。
    089         *
    090         * @og.rev 5.2.3.0 (2010/12/01) 新規追加
    091         *
    092         * @return      ファイルのエンコード
    093         */
    094        public String getEncode() {
    095                return encode;
    096        }
    097
    098        /**
    099         * ファイルを読み取って、文字列を作成します。
    100         *
    101         * データの読取が完全に出来なかったときには、途中までのデータを返します。
    102         * 指定のエンコードが存在しない場合や、ファイルが存在しない場合は、
    103         * RuntimeException を throw します。
    104         *
    105         * @return  ファイルを読み取った文字列
    106         * @throws RuntimeException 指定のエンコードが存在しなかったとき。
    107         */
    108        public String getValue() {
    109                if( value != null ) { return value; }
    110
    111                FileInputStream file = null;
    112                try {
    113                        file = new FileInputStream( filename );
    114                        byte[] buf = new byte[file.available()];
    115                        int len = file.read(buf);
    116                        if( len != buf.length ) {
    117                                String errMsg = "読み取りファイルのデータが切り捨てられました。" +
    118                                                                "File=" + filename + " Length=" + len ;
    119                                LogWriter.log( errMsg );
    120                        }
    121                        if( encode != null ) {
    122                                value = new String( buf,encode );
    123                        }
    124                        else {
    125//                              value = new String( buf );
    126                                value = new String( buf,StringUtil.DEFAULT_CHARSET );   // 5.5.2.6 (2012/05/25) findbugs対応
    127                        }
    128                }
    129                catch( UnsupportedEncodingException ex ) {
    130                        String errMsg = "指定されたエンコーディングがサポートされていません。[" + encode + "]" ;
    131                        throw new RuntimeException( errMsg,ex );
    132                }
    133                catch( IOException ex ) {
    134                        String errMsg = "ファイル名がオープン出来ませんでした。[" + filename + "]" ;
    135                        throw new RuntimeException( errMsg,ex );
    136                }
    137                finally {
    138                        Closer.ioClose( file );
    139                }
    140
    141                return value ;
    142        }
    143
    144        /**
    145         * 指定の区切り文字で分割された文字列配列を取得します。
    146         * 区切り文字が連続している場合は、一つの区切り文字と認識します。
    147         * 処理は、java.util.StringTokenizer で、処理する方法と同一です。
    148         * 例えば、";" を指定すれば、SQL を複数記述しておくことが可能になります。
    149         *
    150         * @param       delim   ファイルを分割する区切り文字
    151         *
    152         * @return  ファイルを読み取った文字列
    153         */
    154        public String[] getValue( final String delim ) {
    155
    156                StringTokenizer token = new StringTokenizer( getValue(),delim );
    157
    158                String[] rtn = new String[token.countTokens()];
    159
    160                for( int i=0; token.hasMoreTokens(); i++ ) {
    161                        rtn[i] = token.nextToken();
    162                }
    163
    164                return rtn ;
    165        }
    166}