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.process; 017 018import java.io.File; 019import java.io.BufferedReader; 020import java.io.PrintWriter; 021import java.io.IOException; 022import java.nio.charset.CharacterCodingException; // 6.3.1.0 (2015/06/28) 023 024import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 025import org.opengion.fukurou.system.OgCharacterException ; // 6.5.0.1 (2016/10/21) 026import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 027import org.opengion.fukurou.system.Closer; 028import org.opengion.fukurou.util.FileUtil; 029import org.opengion.fukurou.util.CommentLineParser; 030import org.opengion.fukurou.util.FileInfo; // 6.4.0.2 (2015/12/11) 031import org.opengion.fukurou.security.HybsCryptography ; // 5.7.2.1 (2014/01/17) 032import static org.opengion.fukurou.system.HybsConst.CR; // 6.3.1.0 (2015/06/28) 033 034/** 035 * FileLineModel は、LineModel を継承した ファイルリスト専用の 036 * LineModel の実装クラスです。 037 * 038 * FileLineModel オブジェクトには、ファイル属性(Level,File,Length,Modify,LineCnt,Biko,MD5) 039 * が設定されます。 040 * オプションで、FILEPATH,ADDRESS,FILENAME 属性を文字列で準備できます。(6.3.1.0 (2015/06/28)) 041 * ADDRESS は、指定ファイルの親フォルダ。FILENAME はファイル名。FILEPATH は、ファイル名を含む 042 * 完全なファイルパスになります。 043 * ※ 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 044 * この、新しい属性に、値をセットする場合は、useFilePath="true" をセットしてください。 045 * ※ 6.3.1.1 (2015/07/10) Modify のフォーマット(modifyForm)を、指定可能にします。 046 * これは、Date型のまま、扱いたい所だが、文字列化しています。 047 * 初期値は、"yyyy/MM/dd HH:mm:ss" です。 048 * 049 * LineCnt と、MD5 は、それぞれ、計算するかどうかのフラグを設定する必要があります。 050 * 051 * ※ useLineCnt=false の場合のLength(文字数)は、File#length() メソッドで求めます。 052 * 一方、useLineCnt=true にすると、行単位に、String#length() を加算するため、 053 * 先のLength(文字数)値とは異なりますのでご注意ください。 054 * 055 * omitCmnt=true にすると、コメント部分を削除した行数と文字数を求めます。 056 * これは、/* から */ の間、// から改行までです。 057 * ただし、"(二重引用符)で囲まれた文字列は、コメントとみなしません。 058 * 059 * 8.1.0.4 (2022/01/28) 060 * さらに、各行の空行はカウントに含めないことにします。 061 * 062 * データの1行分を FileLineModel に割り当てます。 063 * カラム番号は、0 から始まります。カラム名よりカラム番号を求める場合に、 064 * 存在しない場合は、-1 を返します。 065 * カラム番号が -1 の場合は、処理を行いません。 066 * 067 * 注意:このクラスは、同期処理されていません。 068 * 069 * @version 4.0 070 * @author Kazuhiko Hasegawa 071 * @since JDK5.0, 072 */ 073public class FileLineModel extends LineModel { 074 /** 5.7.2.1 (2014/01/17) MD5 キー項目 */ 075 // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 076 private static final String[] KEYS = { "Level","File","Length","Modify","LineCnt","Biko","MD5","FILEPATH","ADDRESS","FILENAME" }; 077 078 private static final int LEVEL = 0; 079 private static final int FILE = 1; 080 private static final int LENGTH = 2; 081 private static final int MODIFY = 3; 082 private static final int LINECNT = 4; 083 private static final int BIKO = 5; 084 private static final int MD5 = 6; // 5.7.2.1 (2014/01/17) 085 private static final int FILEPATH = 7; // 6.3.1.0 (2015/06/28) 086 private static final int ADDRESS = 8; // 6.3.1.0 (2015/06/28) 087 private static final int FILENAME = 9; // 6.3.1.0 (2015/06/28) 088 089 private final boolean useLineCnt ; 090 /** 5.7.2.1 (2014/01/17) MD5 項目追加 */ 091 private final boolean useMD5 ; 092 /** 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する) */ 093 private final boolean omitCmnt ; 094 /** 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性を使う場合は、true */ 095 private final boolean useFilePath ; 096 /** 5.7.4.0 (2014/03/07) コメント削除時の文字数計算で利用するファイルのエンコード */ 097 private String encode = "JISAutoDetect"; 098 private String modifyForm = "yyyy/MM/dd HH:mm:ss" ; // 6.3.1.1 (2015/07/10) 099 100 /** 101 * コンストラクターです。 102 * useLineCnt=false , useMD5=false , omitCmnt=false で初期化されます。 103 * 104 * @og.rev 5.7.2.1 (2014/01/17) MD5対応 105 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する)対応 106 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 107 * 108 */ 109 public FileLineModel() { 110 this( false,false,false,false ); // 6.3.1.0 (2015/06/28) 111 } 112 113 /** 114 * ラインカウントの有無を指定した、コンストラクターです。 115 * useMD5=false , omitCmnt=false で初期化されます。 116 * 117 * @og.rev 4.2.2.0 (2008/05/10) 行数カウントの使用有無 118 * @og.rev 5.7.2.1 (2014/01/17) MD5対応 119 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する)対応 120 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 121 * 122 * @param isLineCnt 行数カウントの使用有無 123 */ 124 public FileLineModel( final boolean isLineCnt ) { 125 this( isLineCnt,false,false,false ); // 6.3.1.0 (2015/06/28) 126 } 127 128 /** 129 * ラインカウントの有無と、MD5計算の有無を指定した、コンストラクターです。 130 * omitCmnt=false で初期化されます。 131 * 132 * @og.rev 5.7.2.1 (2014/01/17) 新規追加(MD5対応) 133 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する)対応 134 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加。 135 * 136 * @param isLineCnt 行数カウントの使用有無 137 * @param isMD5 ファイルのMD5の使用有無 138 */ 139 public FileLineModel( final boolean isLineCnt,final boolean isMD5 ) { 140 this( isLineCnt,isMD5,false,false ); // 6.3.1.0 (2015/06/28) 141 } 142 143 /** 144 * ラインカウントの有無と、MD5計算の有無と、コメント除外の可否を指定した、コンストラクターです。 145 * 146 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する) 147 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 148 * 149 * @param isLineCnt 行数カウントの使用有無 150 * @param isMD5 ファイルのMD5の使用有無 151 * @param isOmit コメント除外の可否(true:除外する) 152 */ 153 public FileLineModel( final boolean isLineCnt,final boolean isMD5,final boolean isOmit ) { 154 this( isLineCnt,isMD5,isOmit,false ); // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 155 } 156 157 /** 158 * ラインカウントの有無と、MD5計算の有無と、コメント除外の可否と、追加属性可否を指定した、コンストラクターです。 159 * 160 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する) 161 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 162 * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 163 * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: [this-escape] サブクラスが初期化される前の'this'エスケープの可能性があります 164 * 165 * @param isLineCnt 行数カウントの使用有無 166 * @param isMD5 ファイルのMD5の使用有無 167 * @param isOmit コメント除外の可否(true:除外する) 168 * @param isPath FILEPATH,ADDRESS,FILENAME 属性の可否(true:使用する) 169 */ 170 public FileLineModel( final boolean isLineCnt,final boolean isMD5,final boolean isOmit,final boolean isPath ) { 171 super( KEYS ); // 8.5.3.2 (2023/10/13) JDK21対応 172// super(); 173 // 4.3.4.4 (2009/01/01) 174 useLineCnt = isLineCnt; 175 useMD5 = isMD5; // 5.7.2.1 (2014/01/17) 176 omitCmnt = isOmit; // 5.7.4.0 (2014/03/07) 177 useFilePath = isPath; // 5.7.4.0 (2014/03/07) 178// init( KEYS ); 179 } 180 181 /** 182 * LineModel を元に、FileLineModel を構築します。 183 * これは、一旦ファイル等にセーブされた FileLineModel 形式を 184 * 元に戻す簡易コンストラクタです。 185 * 186 * @og.rev 4.2.3.0 (2008/05/26) 新規追加 187 * @og.rev 5.7.2.1 (2014/01/17) MD5の設定処理追加 188 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 189 * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 190 * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: [this-escape] サブクラスが初期化される前の'this'エスケープの可能性があります 191 * 192 * @param model 元のLineModel 193 */ 194 public FileLineModel( final LineModel model ) { 195 super( model.getNames() ); // 8.5.3.2 (2023/10/13) JDK21対応 196// super(); 197// // 4.3.4.4 (2009/01/01) 198// init( model.getNames() ); 199 200 final Object[] obj = model.getValues(); 201 202 // 8.5.3.2 (2023/10/13) JDK21対応。setValue が使えないので、コンストラクタから分離する。 203// setValue( LEVEL ,Integer.valueOf( (String)obj[LEVEL] ) ); 204// setValue( FILE ,new File((String)obj[FILE]) ); 205// setValue( LENGTH ,Long.valueOf( (String)obj[LENGTH] ) ); 206// setValue( MODIFY ,(String)obj[MODIFY] ); 207 208 final String cnt = (String)obj[LINECNT] ; 209 useLineCnt = cnt != null && cnt.length() > 0 && ! "null".equalsIgnoreCase( cnt ) ; 210// if( useLineCnt ) { setValue( LINECNT ,cnt ); } 211 212// setValue( BIKO ,(String)obj[BIKO] ); 213 214 // 5.7.2.1 (2014/01/17) 215 final String md5Data = (String)obj[MD5] ; 216 useMD5 = md5Data != null && md5Data.length() > 0 && ! "null".equalsIgnoreCase( md5Data ) ; 217// if( useMD5 ) { setValue( MD5 ,md5Data ); } 218 219 omitCmnt = false; // 5.7.4.0 (2014/03/07) 既存の LineModel から取得できないので、強制設定します。 220 221 // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 222 // 念のため、配列数をチェックしながら処理します。 223 if( obj.length > FILEPATH ) { 224 final String path = (String)obj[FILEPATH] ; 225 useFilePath = path != null && path.length() > 0 && ! "null".equalsIgnoreCase( path ) ; 226// if( useFilePath ) { 227// setValue( FILEPATH ,path ); 228// if( obj.length > ADDRESS ) { setValue( ADDRESS ,(String)obj[ADDRESS] ); } 229// if( obj.length > FILENAME ) { setValue( FILENAME ,(String)obj[FILENAME] ); } 230// } 231 } 232 else { 233 useFilePath = false; 234 } 235 } 236 237 /** 238 * LineModel を元に、FileLineModel を構築します。 239 * <del>これは、一旦ファイル等にセーブされた FileLineModel 形式を元に戻す簡易コンストラクタです。</del> 240 * ※ 元々、コンストラクタでしたが、JDK21で警告が出たため、メソッドを分離しました。処理的には非効率です。 241 * 242 * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: [this-escape] サブクラスが初期化される前の'this'エスケープの可能性があります 243 * 244 * @param model 元のLineModel 245 */ 246// public FileLineModel( final LineModel model ) { 247 public final void copyLineModel( final LineModel model ) { 248// super( model.getNames() ); // 8.5.3.2 (2023/10/13) JDK21対応 249// super(); 250// // 4.3.4.4 (2009/01/01) 251// init( model.getNames() ); 252 253 final Object[] obj = model.getValues(); 254 255 setValue( LEVEL ,Integer.valueOf( (String)obj[LEVEL] ) ); 256 setValue( FILE ,new File((String)obj[FILE]) ); 257 setValue( LENGTH ,Long.valueOf( (String)obj[LENGTH] ) ); 258 setValue( MODIFY ,(String)obj[MODIFY] ); 259 260 final String cnt = (String)obj[LINECNT] ; 261// useLineCnt = cnt != null && cnt.length() > 0 && ! "null".equalsIgnoreCase( cnt ) ; 262 if( useLineCnt ) { setValue( LINECNT ,cnt ); } 263 264 setValue( BIKO ,(String)obj[BIKO] ); 265 266 // 5.7.2.1 (2014/01/17) 267 final String md5Data = (String)obj[MD5] ; 268// useMD5 = md5Data != null && md5Data.length() > 0 && ! "null".equalsIgnoreCase( md5Data ) ; 269 if( useMD5 ) { setValue( MD5 ,md5Data ); } 270 271// omitCmnt = false; // 5.7.4.0 (2014/03/07) 既存の LineModel から取得できないので、強制設定します。 272 273 // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 274 // 念のため、配列数をチェックしながら処理します。 275 if( obj.length > FILEPATH ) { 276 final String path = (String)obj[FILEPATH] ; 277// useFilePath = path != null && path.length() > 0 && ! "null".equalsIgnoreCase( path ) ; 278 if( useFilePath ) { 279 setValue( FILEPATH ,path ); 280 if( obj.length > ADDRESS ) { setValue( ADDRESS ,(String)obj[ADDRESS] ); } 281 if( obj.length > FILENAME ) { setValue( FILENAME ,(String)obj[FILENAME] ); } 282 } 283 } 284// else { 285// useFilePath = false; 286// } 287 } 288 289// /** 290// * LineModel を元に、FileLineModel を構築します。 291// * これは、一旦ファイル等にセーブされた FileLineModel 形式を 292// * 元に戻す簡易コンストラクタです。 293// * 294// * @og.rev 4.2.3.0 (2008/05/26) 新規追加 295// * @og.rev 5.7.2.1 (2014/01/17) MD5の設定処理追加 296// * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 297// * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 298// * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: [this-escape] サブクラスが初期化される前の'this'エスケープの可能性があります … 廃止 299// * 300// * @param model 元のLineModel 301// */ 302// public FileLineModel( final LineModel model ) { 303// super( model.getNames() ); // 8.5.3.2 (2023/10/13) JDK21対応 304//// super(); 305//// // 4.3.4.4 (2009/01/01) 306//// init( model.getNames() ); 307// 308// final Object[] obj = model.getValues(); 309// 310// setValue( LEVEL ,Integer.valueOf( (String)obj[LEVEL] ) ); 311// setValue( FILE ,new File((String)obj[FILE]) ); 312// setValue( LENGTH ,Long.valueOf( (String)obj[LENGTH] ) ); 313// setValue( MODIFY ,(String)obj[MODIFY] ); 314// 315// final String cnt = (String)obj[LINECNT] ; 316// useLineCnt = cnt != null && cnt.length() > 0 && ! "null".equalsIgnoreCase( cnt ) ; 317// if( useLineCnt ) { setValue( LINECNT ,cnt ); } 318// 319// setValue( BIKO ,(String)obj[BIKO] ); 320// 321// // 5.7.2.1 (2014/01/17) 322// final String md5Data = (String)obj[MD5] ; 323// useMD5 = md5Data != null && md5Data.length() > 0 && ! "null".equalsIgnoreCase( md5Data ) ; 324// if( useMD5 ) { setValue( MD5 ,md5Data ); } 325// 326// omitCmnt = false; // 5.7.4.0 (2014/03/07) 既存の LineModel から取得できないので、強制設定します。 327// 328// // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 329// // 念のため、配列数をチェックしながら処理します。 330// if( obj.length > FILEPATH ) { 331// final String path = (String)obj[FILEPATH] ; 332// useFilePath = path != null && path.length() > 0 && ! "null".equalsIgnoreCase( path ) ; 333// if( useFilePath ) { 334// setValue( FILEPATH ,path ); 335// if( obj.length > ADDRESS ) { setValue( ADDRESS ,(String)obj[ADDRESS] ); } 336// if( obj.length > FILENAME ) { setValue( FILENAME ,(String)obj[FILENAME] ); } 337// } 338// } 339// else { 340// useFilePath = false; 341// } 342// } 343 344 /** 345 * File属性値をセットします。 346 * LEVEL,FILE,LENGTH,MODIFY,LINECNT,MD5 の各属性を設定します。 347 * 348 * @og.rev 4.2.2.0 (2008/05/10) 行数カウントの使用有無 349 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 350 * @og.rev 5.7.2.1 (2014/01/17) MD5計算処理の追加 351 * @og.rev 5.7.4.0 (2014/03/07) コメント除外の可否(true:除外する)対応 352 * @og.rev 5.7.7.1 (2014/06/13) omitCmnt=true(コメント除外する) and useMD5=true(MD5計算する) 場合の処理 353 * @og.rev 6.2.1.0 (2015/03/13) ファイルの削除に失敗するため、削除しない。 354 * @og.rev 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 355 * @og.rev 8.1.2.0 (2022/03/10) getMD5 メソッドを getHash メソッドに変更 356 * 357 * @param level ファイルのディレクトリ階層 358 * @param file ファイルオブジェクト 359 */ 360 public void setFileVals( final int level, final File file ) { 361 // 2.0.0 (2024/01/12) PMD 7.0.0 UnnecessaryBoxing 362// setValue( LEVEL ,Integer.valueOf( level ) ); 363 setValue( LEVEL ,level ); 364 setValue( FILE ,file ); 365 setValue( MODIFY ,DateSet.getDate( file.lastModified(),modifyForm ) ); // 6.3.1.1 (2015/07/10) 366 367 // 5.7.7.1 (2014/06/13) omitCmnt=true(コメント除外する) and useMD5=true(MD5計算する) 場合の処理 368 // 別にコメント除去されたファイルを作成して、それの MD5 を求める。 369 File ocFile = null; 370 if( omitCmnt && useMD5 ) { 371 try { 372 ocFile = File.createTempFile( "temp",".tmp" ); 373 ocFile.deleteOnExit(); // 一応、このメソッド内で削除しますが、念のため。 374 } 375 catch( final IOException ex ) { 376 final String errMsg = "コメント除外のMD5計算用 temp ファイルの作成に失敗しました。" + ex.getMessage() ; 377 throw new OgRuntimeException( errMsg,ex ); 378 } 379 } 380 381 if( useLineCnt || omitCmnt ) { 382 final long[] cntVals = getLineCnt( file,ocFile ); // 5.7.7.1 (2014/06/13) 出力ファイルを渡します。 383 setValue( LINECNT ,String.valueOf( cntVals[0] ) ); 384 // 2.0.0 (2024/01/12) PMD 7.0.0 UnnecessaryBoxing 385// setValue( LENGTH ,Long.valueOf( cntVals[1] ) ); 386 setValue( LENGTH ,cntVals[1] ); 387 } 388 else { 389 // 2.0.0 (2024/01/12) PMD 7.0.0 UnnecessaryBoxing 390// setValue( LENGTH ,Long.valueOf( file.length() ) ); 391 setValue( LENGTH ,file.length() ); 392 } 393 394 // 5.7.2.1 (2014/01/17) MD5計算がtrue で、かつ、ファイルの場合、MD5 計算を行います。 395 if( useMD5 && file.isFile() ) { 396 // 5.7.7.1 (2014/06/13) omitCmnt を考慮したMD5計算 397 if( ocFile == null ) { 398// setValue( MD5 ,HybsCryptography.getMD5( file ) ); // 8.1.2.0 (2022/03/10) Modify 399 setValue( MD5 ,HybsCryptography.getHash( "MD5", file ) ); 400 } 401 else { 402// setValue( MD5 ,HybsCryptography.getMD5( ocFile ) ); // 8.1.2.0 (2022/03/10) Modify 403 setValue( MD5 ,HybsCryptography.getHash( "MD5", ocFile ) ); 404 // 6.0.2.4 (2014/10/17) RV java.io.File.delete() の例外的戻り値を無視しています。 405 // 6.2.1.0 (2015/03/13) ファイルの削除に失敗するため、削除しない。 406 } 407 } 408 409 // 6.3.1.0 (2015/06/28) FILEPATH,ADDRESS,FILENAME 属性追加 410 if( useFilePath ) { 411 // FILEPATH は、正規のパス名文字列 を求めるが、エラー時は、絶対パス名文字列 にする。 412 try { 413 setValue( FILEPATH , file.getCanonicalPath() ); // 正規のパス名文字列 414 } 415 catch( final IOException ex ) { 416 setValue( FILEPATH , file.getAbsolutePath() ); // 絶対パス名文字列 417 } 418 419 // ADDRESS は、親の名前なので、直フォルダ名になる。 420 final File parent = file.getParentFile(); 421 if( parent != null ) { 422 setValue( ADDRESS ,parent.getName() ); 423 } 424 425 setValue( FILENAME ,file.getName() ); 426 } 427 } 428 429 /** 430 * コメント削除時の文字数計算で利用するファイルのエンコードをセットします。 431 * 初期値:JISAutoDetect 432 * 433 * @og.rev 5.7.4.0 (2014/03/07) 新規追加 434 * 435 * @param encode コメント削除時の文字数計算で利用するファイルのエンコード 436 */ 437 public void setEncode( final String encode ) { 438 this.encode = encode; 439 } 440 441 /** 442 * File属性値をセットします。 443 * 444 * @param file ファイルオブジェクト 445 */ 446 public void setFile( final File file ) { 447 setValue( FILE,file ); 448 } 449 450 /** 451 * ファイルを取得します。 452 * 453 * @return ファイル 454 */ 455 public File getFile() { 456 return (File)getValue( FILE ); 457 } 458 459 /** 460 * 備考情報属性値をセットします。 461 * 462 * @og.rev 4.2.2.0 (2008/05/10) 行数カウントの使用有無 463 * 464 * @param biko 備考情報 465 */ 466 public void setBiko( final String biko ) { 467 setValue( BIKO,biko ); 468 } 469 470 /** 471 * レベル File属性値を取得します。 472 * 473 * @return ファイルのディレクトリ階層 474 */ 475 public int getLevel() { 476// return ((Integer)getValue( LEVEL )).intValue(); 477 return (Integer)getValue( LEVEL ); 478 } 479 480 /** 481 * ファイルサイズ File属性値を取得します。 482 * 483 * @return ファイルサイズ 484 */ 485 public long getLength() { 486// return ((Long)getValue( LENGTH )).longValue(); 487 return (Long)getValue( LENGTH ); 488 } 489 490 /** 491 * 更新日時(Modify) のフォーマットを、指定します。 492 * 493 * ここで指定しない場合は、"yyyy/MM/dd HH:mm:ss" になります。 494 * Date型で変換できないようなフォームを指定した場合は、実行時に 495 * エラーになりますので、ご注意ください。 496 * 497 * @og.rev 6.3.1.1 (2015/07/10) Modify のフォーマットを、指定可能にします。 498 * 499 * @param form 更新日時のフォーマット 500 * @see java.text.SimpleDateFormat 501 */ 502 public void setModifyForm( final String form ) { 503 if( form != null && !form.isEmpty() ) { 504 modifyForm = form; 505 } 506 } 507 508 /** 509 * 更新日時 File属性値を取得します。 510 * 511 * @return 更新日時(yyyy/MM/dd HH:mm:ss) 512 */ 513 public String getModify() { 514 return (String)getValue( MODIFY ); 515 } 516 517 /** 518 * MD5 File属性値を取得します。 519 * ただし、useMD5 が true でないと値は返しません。 520 * 521 * @og.rev 5.7.2.1 (2014/01/17) 新規追加(MD5対応) 522 * 523 * @return MD5の値 524 */ 525 public String getMD5() { 526 return (String)getValue( MD5 ); 527 } 528 529 /** 530 * 行数と文字数を取得します。 531 * 行数カウントとファイルの文字数カウント(バイト数ではありません)を行います。 532 * ※ useLineCnt=false の場合のLength(文字数)は、File#length() メソッドで求めます。 533 * 一方、useLineCnt=true にすると、行単位に、String#length() を加算するため、 534 * 先のLength(文字数)値とは異なりますのでご注意ください。 535 * 536 * 結果は、long型の配列で返します。[0]が行数で、[1]が文字数です。 537 * omitCmnt 属性を使用した場合は、コメント部分を削除した行数と文字数を求めます。 538 * これは、/* から */ の間、// から改行までです。 539 * ただし、"(二重引用符)で囲まれた文字列は、コメントとみなしません。 540 * 541 * @og.rev 5.7.4.0 (2014/03/07) 行数カウントとファイルの文字数カウントを行う。 542 * @og.rev 5.7.7.1 (2014/06/13) omitCmnt=true(コメント除外する) and useMD5=true(MD5計算する) 場合の処理 543 * @og.rev 6.2.1.0 (2015/03/13) ディレクトリ以外からファイルのみに対象を変更。 544 * @og.rev 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 545 * @og.rev 6.4.0.2 (2015/12/11) CommentLineParser 改造。 546 * @og.rev 6.5.0.1 (2016/10/21) CharacterCodingException は、OgCharacterException に変換する。 547 * @og.rev 8.1.0.4 (2022/01/28) 各行の空行はカウントに含めないことにする。 548 * 549 * @param file 行数を数えるファイルオブジェクト 550 * @param ocFile omitCmnt=trueの場合に、MD5計算する時の、仮出力ファイル(nullの場合は、無視) 551 * 552 * @return long型の配列([0]が行数で、[1]が文字数) 553 * @og.rtnNotNull 554 */ 555 private long[] getLineCnt( final File file,final File ocFile ) { 556 long lineCnt = 0L; // 行数 557 long charCnt = 0L; // 文字数 558 559 final BufferedReader reader = FileUtil.getBufferedReader( file,encode ); 560 561 // 5.7.7.1 (2014/06/13) omitCmnt=true(コメント除外する) and useMD5=true(MD5計算する) 場合の処理 562 PrintWriter writer = null; 563 if( ocFile != null ) { writer = FileUtil.getPrintWriter( ocFile ,encode ); } 564 565 // 6.4.0.2 (2015/12/11) CommentLineParser 改造 566 final CommentLineParser clp = omitCmnt ? new CommentLineParser( FileInfo.getSUFIX( file ) ) : null; 567 try { 568 // 6.2.1.0 (2015/03/13) ディレクトリ以外からファイルのみに対象を変更。 569 if( file.isFile() ) { 570 String line ; 571 while((line = reader.readLine()) != null) { 572 if( omitCmnt ) { 573 line = clp.line( line ); 574 // 8.1.0.4 (2022/01/28) 各行の空行はカウントに含めないことにする。 575// if( line == null ) { continue; } // 戻り値が null の場合は、行として不成立 576 if( line == null || line.isEmpty() ) { continue; } // 戻り値が nullか 空行の場合は、含めない 577 if( writer != null ) { writer.println( line ); } // 5.7.7.1 (2014/06/13) 578 } 579 580 lineCnt++; 581 charCnt += line.length(); 582 } 583 } 584 } 585 // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 586 catch( final CharacterCodingException ex ) { 587 final String errMsg = "文字のエンコード・エラーが発生しました。" + CR 588 + " ファイルのエンコードが指定のエンコードと異なります。" + CR 589 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 590 throw new OgCharacterException( errMsg,ex ); // 6.5.0.1 (2016/10/21) 591 } 592 catch( final IOException ex ) { 593 final String errMsg = "ファイルカウント中に例外が発生しました。" + CR 594 + " [" + file.getPath() + "] , Encode=[" + encode + "]" ; 595 throw new OgRuntimeException( errMsg,ex ); 596 } 597 finally { 598 Closer.ioClose( reader ) ; 599 Closer.ioClose( writer ) ; // 5.7.7.1 (2014/06/13) ioClose は、引数が null なら無視します。 600 } 601 602 return new long[] { lineCnt,charCnt }; 603 } 604}