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 */
016 package org.opengion.fukurou.util;
017
018 import java.io.BufferedInputStream;
019 import java.io.BufferedOutputStream;
020 import java.io.BufferedReader;
021 import java.io.BufferedWriter;
022 import java.io.File;
023 import java.io.InputStream;
024 import java.io.FileInputStream;
025 import java.io.FileNotFoundException;
026 import java.io.FileOutputStream;
027 import java.io.IOException;
028 import java.io.InputStreamReader;
029 import java.io.OutputStream;
030 import java.io.OutputStreamWriter;
031 import java.io.PrintWriter;
032 import java.io.UnsupportedEncodingException;
033 import java.io.Writer;
034 import java.util.Collections;
035 import java.util.List;
036
037 // import java.nio.ByteBuffer;
038 import java.nio.channels.FileChannel;
039
040 /**
041 * FileUtil.java は、å?通的に使用されã‚?File関連メソãƒ?ƒ‰を集ç´?�—たã?クラスですã?
042 *
043 * 全変数は、public static final 宣è¨?�•れており、å?メソãƒ?ƒ‰は、public static synchronized 宣è¨?�•れてã�?�¾すã?
044 *
045 * @og.group ユーãƒ?‚£リãƒ?‚£
046 *
047 * @version 4.0
048 * @author Kazuhiko Hasegawa
049 * @since JDK5.0,
050 */
051 public final class FileUtil {
052 private static final NonClosePrintWriter outWriter = new NonClosePrintWriter( System.out );
053 private static final NonClosePrintWriter errWriter = new NonClosePrintWriter( System.err );
054
055 /**
056 * すべてã�?staticメソãƒ?ƒ‰なので、コンストラクタを呼び出さなくしておきますã?
057 *
058 */
059 private FileUtil() {}
060
061 /** シスãƒ?ƒ 依存ã?改行記号をセãƒ?ƒˆしますã? */
062 private static final String CR = System.getProperty("line.separator");
063
064 /** 5.6.1.2 (2013/02/22) UNIX系のファイル名を表すセパレータæ–??*/
065 private static final char UNIX_SEPARATOR = '/';
066
067 /** 5.6.1.2 (2013/02/22) Windwos系のファイル名を表すセパレータæ–??*/
068 private static final char WINDOWS_SEPARATOR = '\\';
069
070 /** 5.6.1.2 (2013/02/22) ファイルの拡張子ã?区åˆ?‚Šを表す文å?*/
071 public static final char EXTENSION_SEPARATOR = '.';
072
073 /**
074 * Fileオブジェクトとエンコードよã‚?PrintWriterオブジェクトを作æ?しますã?
075 *
076 * @param file 出力するファイルオブジェクãƒ?
077 * @param encode ファイルのエンコーãƒ?
078 *
079 * @return PrintWriterオブジェクãƒ?
080 * @throws RuntimeException 何らかã?エラーが発生したå?å�?
081 */
082 public static PrintWriter getPrintWriter( final File file,final String encode ) {
083 return getPrintWriter( file,encode,false );
084 }
085
086 /**
087 * Fileオブジェクトとエンコードよã‚?PrintWriterオブジェクトを作æ?しますã?
088 *
089 * @param file 出力するファイルオブジェクãƒ?
090 * @param encode ファイルのエンコーãƒ?
091 * @param append ファイルを追åŠ?ƒ¢ーãƒ?true)にするかどã�?�‹
092 *
093 * @return PrintWriterオブジェクãƒ?
094 * @throws RuntimeException 何らかã?エラーが発生したå?å�?
095 */
096 public static PrintWriter getPrintWriter( final File file,final String encode,final boolean append ) {
097 final PrintWriter writer ;
098
099 try {
100 writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
101 new FileOutputStream(file,append) ,encode )));
102 }
103 catch( UnsupportedEncodingException ex ) {
104 String errMsg = "æŒ?®šされたエンコーãƒ?‚£ングがサポã?トされてã�?�¾せんã€? + CR
105 + ex.getMessage() + CR
106 + "File=[" + file + " , encode=[" + encode + "]" ;
107 throw new RuntimeException( errMsg,ex );
108 }
109 catch( FileNotFoundException ex ) { // 3.6.1.0 (2005/01/05)
110 String errMsg = "ファイル名がオープン出来ませんでしたã€? + CR
111 + ex.getMessage() + CR
112 + "File=[" + file + " , encode=[" + encode + "]" ;
113 throw new RuntimeException( errMsg,ex );
114 }
115
116 return writer ;
117 }
118
119 /**
120 * ファイル名よりã?PrintWriterオブジェクトを作æ?する簡易メソãƒ?ƒ‰ですã?
121 *
122 * これは、ファイル名ã?、フルパスで、追åŠ?ƒ¢ードで、UTF-8 エンコードã?
123 * ログファイルをå?力するå?合に使用しますã?
124 * またã?ファイル名にã€?System.out" とã€?System.err" を指定できますã?
125 * そã?場合ã?、標準å?力ã?またã?、標準エラー出力に出力されますã?
126 * "System.out" とã€?System.err" を指定したå?合ã?、NonClosePrintWriter
127 * オブジェクトが返されますã?これは、close() 処ç�?�Œ呼ばれてもã?何もしなã�?
128 * クラスですã?またã?常にå†?ƒ¨キャãƒ?‚·ュの同じオブジェクトが返されますã?
129 *
130 * @param file 出力するファイルå�?
131 *
132 * @return PrintWriterオブジェクãƒ?
133 * @throws RuntimeException 何らかã?エラーが発生したå?å�?
134 * @throws IllegalArgumentException ファイル名が null の場å�?
135 */
136 public static PrintWriter getLogWriter( final String file ) {
137 if( file == null ) {
138 String errMsg = "ファイル名に、null はæŒ?®šできませんã€?;
139 throw new IllegalArgumentException( errMsg );
140 }
141
142 final PrintWriter writer ;
143 if( "System.out".equalsIgnoreCase( file ) ) {
144 writer = outWriter ;
145 }
146 else if( "System.err".equalsIgnoreCase( file ) ) {
147 writer = errWriter ;
148 }
149 else {
150 writer = getPrintWriter( new File( file ),"UTF-8",true );
151 }
152
153 return writer ;
154 }
155
156 /**
157 * OutputStreamとエンコードよã‚?PrintWriterオブジェクトを作æ?しますã?
158 *
159 * @og.rev 5.5.2.0 (2012/05/01) 新規追åŠ?
160 *
161 * @param os 利用するOutputStream
162 * @param encode ファイルのエンコーãƒ?
163 *
164 * @return PrintWriterオブジェクãƒ?
165 * @throws RuntimeException 何らかã?エラーが発生したå?å�?
166 */
167 public static PrintWriter getPrintWriter( final OutputStream os,final String encode ) {
168 final PrintWriter writer ;
169
170 try {
171 writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
172 os ,encode )));
173 }
174 catch( UnsupportedEncodingException ex ) {
175 String errMsg = "æŒ?®šされたエンコーãƒ?‚£ングがサポã?トされてã�?�¾せんã€? + CR
176 + ex.getMessage() + CR
177 + "encode=[" + encode + "]" ;
178 throw new RuntimeException( errMsg,ex );
179 }
180 return writer ;
181 }
182
183 /**
184 * PrintWriter を継承した、JspWriterなどの Writer 用のクラスを定義しますã?
185 *
186 * 例えば、JspWriterなどの JSP/Servlet等ã?フレーãƒ?ƒ¯ークで使用されã‚?
187 * Writer では、flush ã‚?close 処ç�??、フレーãƒ?ƒ¯ークå†?�§行われますã?
188 * そã?場合ã?通常のファイルと同じ用に、flush ã‚?close をアプリケーション側で
189 * 行うと、å?部処ç�?š„に不整合が発生したり、最悪の場合エラーになりますã?
190 * こã?クラスは、NonFlushPrintWriter クラスのオブジェクトを返しますã?
191 * これはã€??常の、new PrintWriter( Writer ) で、求めるã?と、ほとんど同様ã?
192 * 処ç�?‚’行いますが、close() と flush() メソãƒ?ƒ‰が呼ばれてもã?何もしませんã€?
193 *
194 * @param writer 出力するWriteオブジェクãƒ?NonFlushPrintWriterクラス)
195 *
196 * @return PrintWriterオブジェクãƒ?
197 */
198 public static PrintWriter getNonFlushPrintWriter( final Writer writer ) {
199 return new NonFlushPrintWriter( writer );
200 }
201
202 /**
203 * Fileオブジェクトとエンコードよã‚?BufferedReaderオブジェクトを作æ?しますã?
204 *
205 * @param file 入力するファイルオブジェクãƒ?
206 * @param encode ファイルのエンコーãƒ?
207 *
208 * @return BufferedReaderオブジェクãƒ?
209 * @throws RuntimeException 何らかã?エラーが発生したå?å�?
210 */
211 public static BufferedReader getBufferedReader( final File file,final String encode ) {
212 final BufferedReader reader ;
213
214 try {
215 reader = new BufferedReader(new InputStreamReader(
216 new FileInputStream( file ) ,encode ));
217 }
218 catch( UnsupportedEncodingException ex ) {
219 String errMsg = "æŒ?®šされたエンコーãƒ?‚£ングがサポã?トされてã�?�¾せんã€? + CR
220 + ex.getMessage() + CR
221 + "FIle=[" + file + " , encode=[" + encode + "]" ;
222 throw new RuntimeException( errMsg,ex );
223 }
224 catch( FileNotFoundException ex ) {
225 String errMsg = "ファイル名がオープン出来ませんでしたã€? + CR
226 + ex.getMessage() + CR
227 + "FIle=[" + file + " , encode=[" + encode + "]" ;
228 throw new RuntimeException( errMsg,ex );
229 }
230
231 return reader ;
232 }
233
234 /**
235 * æŒ?®šã?ファイル名が、実際に存在してã�?‚‹かどã�?�‹をチェãƒ?‚¯しますã?
236 * 存在しなã�??合ã?ã€?¼’秒毎にã€?¼“回確認しますã?
237 * それでも存在しなã�??合ã?、エラーを返しますã?
238 * return されるFileオブジェクトã?、正規ã?形å¼?CanonicalFile)ですã?
239 *
240 * @param dir フォルãƒ?��
241 * @param filename ファイルå�?
242 *
243 * @return 存在チェãƒ?‚¯(なければ null/あれば、CanonicalFile)
244 */
245 public static File checkFile( final String dir, final String filename ) {
246 return checkFile( dir,filename,3 );
247 }
248
249 /**
250 * æŒ?®šã?ファイル名が、実際に存在してã�?‚‹かどã�?�‹をチェãƒ?‚¯しますã?
251 * 存在しなã�??合ã?ã€?¼’秒毎に、指定ã?回数åˆ?¢º認しますã?
252 * それでも存在しなã�??合ã?、エラーを返しますã?
253 * return されるFileオブジェクトã?、正規ã?形å¼?CanonicalFile)ですã?
254 *
255 * @param dir フォルãƒ?��
256 * @param filename ファイルå�?
257 * @param count 回数æŒ?®?
258 *
259 * @return 存在チェãƒ?‚¯(なければ null/あれば、CanonicalFile)
260 */
261 public static File checkFile( final String dir, final String filename,final int count ) {
262 File file = null;
263
264 int cnt = count;
265 while( cnt > 0 ) {
266 file = new File( dir,filename );
267 if( file.exists() ) { break; }
268 else {
269 if( cnt == 1 ) { return null; } // 残り?‘回の場合ã?ã€?¼’秒å¾?©Ÿせずに即抜けるã?
270 try { Thread.sleep( 2000 ); } // ?’秒å¾?©?
271 catch ( InterruptedException ex ) {
272 System.out.println( "InterruptedException" );
273 }
274 System.out.println();
275 System.out.print( "CHECK File Error! CNT=" + cnt );
276 System.out.print( " File=" + file.getAbsolutePath() );
277 }
278 cnt--;
279 }
280
281 // ファイルの正式パス名ã?取å¾?
282 try {
283 return file.getCanonicalFile() ;
284 }
285 catch( IOException ex ) {
286 String errMsg = "ファイルの正式パス名が取得できませんã€?" + file.getAbsolutePath() + "]";
287 throw new RuntimeException( errMsg,ex );
288 }
289 }
290
291 /**
292 * ファイルのバイナリコピã?を行いますã?
293 *
294 * copy( File,File,false ) を呼び出しますã?
295 *
296 * @og.rev 5.1.6.0 (2010/05/01) 戻りå?に、true/false æŒ?®šしますã?
297 *
298 * @param fromFile コピã?å…?ƒ•ァイルå�?
299 * @param toFile コピã?先ファイルå�?
300 *
301 * @return バイナリコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
302 * @see #copy( File,File,boolean )
303 */
304 public static boolean copy( final String fromFile,final String toFile ) {
305 return copy( new File( fromFile ), new File( toFile ), false );
306 }
307
308 /**
309 * ファイルのバイナリコピã?を行いますã?
310 *
311 * copy( File,File,boolean ) を呼び出しますã?
312 * 第?“引数の、keepTimeStamp=true で、コピã?å…??ファイルのタイãƒ?‚¹タンプをã€?
313 * コピã?先にもセãƒ?ƒˆしますã?
314 *
315 * @og.rev 5.1.6.0 (2010/05/01) 戻りå?に、true/false æŒ?®šしますã?
316 *
317 * @param fromFile コピã?å…?ƒ•ァイルå�?
318 * @param toFile コピã?先ファイルå�?
319 * @param keepTimeStamp タイãƒ?‚¹タンプ維持[true/false]
320 *
321 * @return バイナリコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
322 * @see #copy( File,File,boolean )
323 */
324 // public static boolean copy( final String fromFile,final String toFile,final boolean changeCrLf ) {
325 public static boolean copy( final String fromFile,final String toFile,final boolean keepTimeStamp ) {
326 return copy( new File( fromFile ), new File( toFile ), keepTimeStamp );
327 }
328
329 /**
330 * ファイルのバイナリコピã?を行いますã?
331 *
332 * copy( File,File,false ) を呼び出しますã?
333 *
334 * @og.rev 5.1.6.0 (2010/05/01) 戻りå?に、true/false æŒ?®šしますã?
335 *
336 * @param fromFile コピã?å…?ƒ•ァイル
337 * @param toFile コピã?先ファイル
338 *
339 * @return バイナリコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
340 * @see #copy( File,File,boolean )
341 */
342 public static boolean copy( final File fromFile,final File toFile ) {
343 return copy( fromFile, toFile, false );
344 }
345
346 /**
347 * ファイルのバイナリコピã?を行いますã?
348 *
349 * 第?“引数の、keepTimeStamp=true で、コピã?å…??ファイルのタイãƒ?‚¹タンプをã€?
350 * コピã?先にもセãƒ?ƒˆしますã?
351 * toFile がã?ãƒ?‚£レクトリの場合ã?、fromFile のファイル名をそã?ままコピã?しますã?
352 * fromFile がディレクトリの場合ã?、エラーにしますã?
353 * copyDirectry( File,Fileboolean )を使用してくださいã€?自動å?ç�??してã�?�¾せん)
354 *
355 * @og.rev 5.1.6.0 (2010/05/01) 新規追åŠ?
356 * @og.rev 5.6.5.2 (2013/06/21) ByteBufferを利用した方式からã?transferTo を使用する方式に変更
357 *
358 * @param fromFile コピã?å…?ƒ•ァイル
359 * @param toFile コピã?先ファイル
360 * @param keepTimeStamp タイãƒ?‚¹タンプ維持[true/false]
361 *
362 * @return バイナリコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
363 * @see #copyDirectry( File,File,boolean )
364 */
365 public static boolean copy( final File fromFile,final File toFile,final boolean keepTimeStamp ) {
366 FileInputStream inFile = null;
367 FileOutputStream outFile = null;
368 FileChannel fin = null;
369 FileChannel fout = null;
370
371 File tempToFile = toFile ;
372 try {
373 // fromFileがã?ãƒ?‚£レクトリの場合ã?、エラー
374 if( fromFile.isDirectory() ) {
375 System.err.println( fromFile + " がディレクトリのため、å?ç�?�§きませんã€? );
376 return false;
377 }
378 // toFileがã?ãƒ?‚£レクトリの場合ã?、そのパスでファイル名をfromFileから取り出すã?
379 if( toFile.isDirectory() ) {
380 tempToFile = new File( toFile,fromFile.getName() );
381 }
382 inFile = new FileInputStream( fromFile );
383 outFile = new FileOutputStream( tempToFile );
384
385 fin = inFile.getChannel();
386 fout = outFile.getChannel();
387
388 // 5.6.5.2 (2013/06/21) ByteBufferを利用した方式からã?transferTo を使用する方式に変更
389 // ByteBuffer buffer = ByteBuffer.allocateDirect( BUFSIZE );
390 // while ( (fin.read(buffer) != -1) || buffer.position() > 0) {
391 // buffer.flip();
392 // fout.write( buffer );
393 // buffer.compact();
394 // }
395
396 fin.transferTo(0, fin.size(), fout );
397
398 }
399 catch ( IOException ex ) {
400 System.out.println(ex.getMessage());
401 return false;
402 }
403 finally {
404 Closer.ioClose( inFile ) ;
405 Closer.ioClose( outFile );
406 Closer.ioClose( fin ) ;
407 Closer.ioClose( fout );
408 }
409
410 if( keepTimeStamp ) {
411 return tempToFile.setLastModified( fromFile.lastModified() );
412 }
413
414 return true;
415 }
416 // public static boolean copy( final File fromFile,final File toFile,final boolean keepTimeStamp ) {
417 // BufferedInputStream fromStream = null;
418 // BufferedOutputStream toStream = null;
419 // File tempToFile = toFile ;
420 // try {
421 // // fromFileがã?ãƒ?‚£レクトリの場合ã?、エラー
422 // if( fromFile.isDirectory() ) {
423 // System.err.println( fromFile + " がディレクトリのため、å?ç�?�§きませんã€? );
424 // return false;
425 // }
426 // // toFileがã?ãƒ?‚£レクトリの場合ã?、そのパスでファイル名をfromFileから取り出すã?
427 // if( toFile.isDirectory() ) {
428 // tempToFile = new File( toFile,fromFile.getName() );
429 // }
430 //
431 // fromStream = new BufferedInputStream( new FileInputStream( fromFile ) );
432 // toStream = new BufferedOutputStream( new FileOutputStream( tempToFile ) );
433 //
434 // boolean isOK = copy( fromStream,toStream );
435 // if( !isOK ) { return false; }
436 //
437 // }
438 // catch ( IOException ex ) {
439 // System.out.println(ex.getMessage());
440 // return false;
441 // }
442 // finally {
443 // Closer.ioClose( fromStream ) ;
444 // Closer.ioClose( toStream ) ;
445 // }
446 //
447 // if( keepTimeStamp ) {
448 // tempToFile.setLastModified( fromFile.lastModified() );
449 // }
450 //
451 // return true;
452 // }
453
454 private static final byte B_CR = (byte)0x0d ; // '\r'
455 private static final byte B_LF = (byte)0x0a ; // '\n'
456 private static final int BUFSIZE = 8192 ; // 5.1.6.0 (2010/05/01)
457
458 /**
459 * ファイルのバイナリコピã?を行いますã?
460 *
461 * こã?ファイルコピã?は、バイナリファイルの 改行コードを
462 * CR+LF に統ä¸?�—ますã?またã?UTF-8 の BOM(0xef,0xbb,0xbf) があれã?ã€?
463 * 取り除きますã?
464 *
465 * @og.rev 5.1.6.0 (2010/05/01) 新規追åŠ?
466 *
467 * @param fromFile コピã?å…?ƒ•ァイル
468 * @param toFile コピã?先ファイル
469 *
470 * @return バイナリコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
471 */
472 public static boolean changeCrLfcopy( final File fromFile,final File toFile ) {
473 BufferedInputStream fromStream = null;
474 BufferedOutputStream toStream = null;
475 File tempToFile = toFile ;
476 try {
477 // ãƒ?‚£レクトリの場合ã?、そのパスでファイル名をfromFileから取り出すã?
478 if( toFile.isDirectory() ) {
479 tempToFile = new File( toFile,fromFile.getName() );
480 }
481 fromStream = new BufferedInputStream( new FileInputStream( fromFile ) );
482 toStream = new BufferedOutputStream( new FileOutputStream( tempToFile ) );
483
484 // int BUFSIZE = 8192 ; // 5.1.6.0 (2010/05/01) static final定義
485 byte[] buf = new byte[BUFSIZE];
486 int len ;
487 // 4.2.3.0 (2008/05/26) changeCrLf 属æ?対å¿?
488
489 boolean bomCheck = true; // æœ??のä¸?›žã�?�‘ã€?¼¢?¯?チェãƒ?‚¯を行うã€?
490 byte bt = (byte)0x00; // バッファのæœ?¾Œとæœ??の比è¼?™‚に使用
491 while( (len = fromStream.read(buf,0,BUFSIZE)) != -1 ) {
492 int st = 0;
493 if( bomCheck && len >= 3 &&
494 buf[0] == (byte)0xef &&
495 buf[1] == (byte)0xbb &&
496 buf[2] == (byte)0xbf ) {
497 st = 3;
498 }
499 else {
500 // バッファのæœ?¾Œが CR で、å?頭ã�?LF の場合ã?LF をパスしますã?
501 if( bt == B_CR && buf[0] == B_LF ) {
502 st = 1 ;
503 }
504 }
505 bomCheck = false;
506
507 for( int i=st;i<len;i++ ) {
508 bt = buf[i] ;
509 if( bt == B_CR || bt == B_LF ) {
510 toStream.write( (int)B_CR ); // CR
511 toStream.write( (int)B_LF ); // LF
512 // CR+LF の場å�?
513 if( bt == B_CR && i+1 < len && buf[i+1] == B_LF ) {
514 i++;
515 bt = buf[i] ;
516 }
517 }
518 else {
519 toStream.write( (int)bt );
520 }
521 }
522 }
523 // æœ?¾Œが改行コードでなければ、改行コードを追åŠ?�—ますã?
524 // ãƒ?‚ストコピã?との互換性のため
525 if( bt != B_CR && bt != B_LF ) {
526 toStream.write( (int)B_CR ); // CR
527 toStream.write( (int)B_LF ); // LF
528 }
529 }
530 catch ( IOException ex ) {
531 System.out.println(ex.getMessage());
532 return false;
533 }
534 finally {
535 Closer.ioClose( fromStream ) ;
536 Closer.ioClose( toStream ) ;
537 }
538
539 return true;
540 }
541
542 /**
543 * 入出力ストリーãƒ?–“でãƒ??タの転送を行いますã?
544 *
545 * ここでは、すでに作æ?されたストリーãƒ?�«基づきã?ãƒ??タの入出力を行いますã?
546 * よって、å?にフォルãƒ?½œæ?ã‚??存在チェãƒ?‚¯、ファイルの削除などのå¿?¦�な処ç�??
547 * 済まして置ã�?�¦くださいã€?
548 * またã?こã?メソãƒ?ƒ‰å†?�§、ストリーãƒ??クロース処ç�??行ってã�?�¾せんã€?
549 *
550 * @og.rev 5.1.6.0 (2010/05/01) 新規追åŠ?
551 *
552 * @param input 入力ストリーãƒ?
553 * @param output 出力ストリーãƒ?
554 *
555 * @return ãƒ??タ転送が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
556 */
557 public static boolean copy( final InputStream input,final OutputStream output ) {
558 if( input == null ) {
559 System.err.println( "入力ストリーãƒ?�Œ 作æ?されてã�?�¾せんã€? );
560 return false;
561 }
562
563 if( output == null ) {
564 System.err.println( "出力ストリーãƒ?�Œ 作æ?されてã�?�¾せんã€? );
565 return false;
566 }
567
568 try {
569 byte[] buf = new byte[BUFSIZE];
570 int len;
571 while((len = input.read(buf)) != -1) {
572 output.write(buf, 0, len);
573 }
574 }
575 catch ( IOException ex ) {
576 System.out.println( ex.getMessage() );
577 return false;
578 }
579 // finally {
580 // Closer.ioClose( input );
581 // Closer.ioClose( output );
582 // }
583 return true ;
584 }
585
586 /**
587 * 再帰処ç�?�§ãƒ?‚£レクトリのコピã?を行いますã?
588 *
589 * æŒ?®šされたコピã?å…?ƒ‡ィレクトリがディレクトリでなかったり存在しなã�?�¨きã? falseを返しますã?
590 *
591 * @og.rev 4.3.0.0 (2008/07/24) 追åŠ?
592 * @og.rev 5.1.6.0 (2010/05/01) 戻りå?に、true/false æŒ?®šしますã?
593 *
594 * @param fromDir コピã?å…?ƒ‡ィレクトリå�?
595 * @param toDir コピã?先ディレクトリå�?
596 *
597 * @return ãƒ?‚£レクトリのコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
598 */
599 public static boolean copyDirectry( final String fromDir, final String toDir ) {
600 return copyDirectry( new File( fromDir ), new File( toDir ),false );
601 }
602
603 /**
604 * 再帰処ç�?�§ãƒ?‚£レクトリをコピã?しますã?
605 *
606 * æŒ?®šされたコピã?å…?ƒ‡ィレクトリがディレクトリでなかったり存在しなã�?�¨きã? falseを返しますã?
607 *
608 * @og.rev 4.3.0.0 (2008/07/24) 追åŠ?
609 * @og.rev 5.1.6.0 (2010/05/01) å†?ƒ¨処ç�?‚’若干変更しますã?
610 *
611 * @param fromDir コピã?å…?ƒ‡ィレクトリ
612 * @param toDir コピã?先ディレクトリ
613 *
614 * @return ãƒ?‚£レクトリのコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
615 */
616 public static boolean copyDirectry( final File fromDir, final File toDir ) {
617 return copyDirectry( fromDir, toDir, false );
618 }
619
620 /**
621 * 再帰処ç�?�§ãƒ?‚£レクトリをコピã?しますã?
622 *
623 * æŒ?®šされたコピã?å…?ƒ‡ィレクトリがディレクトリでなかったり存在しなã�?�¨きã? falseを返しますã?
624 *
625 * @og.rev 4.3.0.0 (2008/07/24) 追åŠ?
626 * @og.rev 5.1.6.0 (2010/05/01) å†?ƒ¨処ç�?‚’若干変更しますã?
627 * @og.rev 5.3.7.0 (2011/07/01) フォルãƒ?�«アクセスできなã�??合ã?、エラーを返しますã?
628 *
629 * @param fromDir コピã?å…?ƒ‡ィレクトリ
630 * @param toDir コピã?先ディレクトリ
631 * @param keepTimeStamp タイãƒ?‚¹タンプ維持[true/false]
632 *
633 * @return ãƒ?‚£レクトリのコピã?が正常に終äº?�—たかどã�?�‹[true:成功/false:失敗]
634 */
635 public static boolean copyDirectry( final File fromDir, final File toDir, final boolean keepTimeStamp ) {
636 // コピã?å…?�Œãƒ?‚£レクトリでなã�??合ã?falseを返す
637 // 4.3.4.4 (2009/01/01)
638 if( !fromDir.exists() || !fromDir.isDirectory() ) {
639 System.err.println( fromDir + " ã�?ãƒ?‚£レクトリでなã�?�‹、存在しませんã€? );
640 return false;
641 }
642
643 // 4.3.4.4 (2009/01/01)
644 if( !toDir.exists() ) {
645 // ãƒ?‚£レクトリを作æ?する
646 if( !toDir.mkdirs() ) {
647 System.err.println( toDir + " の ãƒ?‚£レクトリ作æ?に失敗しましたã€? );
648 return false;
649 }
650 }
651
652 // ãƒ?‚£レクトリå†??ファイルをすべて取得すã‚?
653 File[] files = fromDir.listFiles();
654
655 // 5.3.7.0 (2011/07/01) フォルãƒ?�«アクセスできなã�??合ã?、エラー
656 if( files == null ) {
657 System.err.println( fromDir + " はアクセスできませんã€? );
658 return false;
659 }
660
661 // ãƒ?‚£レクトリå†??ファイルに対しコピã?処ç�?‚’行う
662 boolean flag = true;
663 for( int i = 0; files.length>i; i++ ){
664 if( files[i].isDirectory() ){ // ãƒ?‚£レクトリã�?�£たå?合ã?再帰呼び出しを行う
665 flag = copyDirectry( files[i], new File( toDir, files[i].getName()),keepTimeStamp );
666 }
667 else{ // ファイルã�?�£たå?合ã?ファイルコピã?処ç�?‚’行う
668 flag = copy( files[i], new File( toDir, files[i].getName()),keepTimeStamp );
669 }
670 if( !flag ) { return false; }
671 }
672 return true;
673 }
674 // public static boolean copyDirectry( final File fromDirectry, final File toDirectry ) {
675 // // コピã?å…?�Œãƒ?‚£レクトリでなã�??合ã?falseを返す
676 // // 4.3.4.4 (2009/01/01)
677 // if( !fromDirectry.exists() || !fromDirectry.isDirectory() ) { return false; }
678 //
679 // // 4.3.4.4 (2009/01/01)
680 // boolean flag = true;
681 // if( !toDirectry.exists() ) {
682 // // ãƒ?‚£レクトリを作æ?する
683 // flag = toDirectry.mkdirs();
684 // if( ! flag ) { System.err.println( toDirectry.getName() + " の ãƒ?‚£レクトリ作æ?に失敗しましたã€? ); }
685 // }
686 //
687 // // ãƒ?‚£レクトリå†??ファイルをすべて取得すã‚?
688 // File[] files = fromDirectry.listFiles();
689 //
690 // // ãƒ?‚£レクトリå†??ファイルに対しコピã?処ç�?‚’行う
691 // for( int i = 0; files.length>i; i++ ){
692 // if( files[i].isDirectory() ){ // ãƒ?‚£レクトリã�?�£たå?合ã?再帰呼び出しを行う
693 // copyDirectry(
694 // new File( fromDirectry.toString(), files[i].getName() ),
695 // new File( toDirectry.toString(), files[i].getName()));
696 // }
697 // else{ // ファイルã�?�£たå?合ã?ファイルコピã?処ç�?‚’行う
698 // copy(
699 // new File( fromDirectry.toString(), files[i].getName() ),
700 // new File( toDirectry.toString(), files[i].getName()) );
701 // }
702 // }
703 // return true;
704 // }
705
706 /**
707 * æŒ?®šされたファイル及ã?ãƒ?‚£レクトを削除しますã?
708 * ãƒ?‚£レクトリの場合ã?サブフォルãƒ?�Šびファイルも削除しますã?
709 * ?‘つでもファイルの削除に失敗したå?合ã?そã?時点で処ç�?‚’中断しfalseを返しますã?
710 *
711 * @og.rev 5.3.7.0 (2011/07/01) フォルãƒ?�«アクセスできなã�??合ã?、エラーを返しますã?
712 *
713 * @param file 削除ファイル/ãƒ?‚£レクトリ
714 *
715 * @return ファイル/ãƒ?‚£レクトリの削除に終äº?�—たかどã�?�‹[true:成功/false:失敗]
716 */
717 public static boolean deleteFiles( final File file ) {
718 if( file.exists() ) {
719 if( file.isDirectory() ) {
720 File[] list = file.listFiles();
721
722 // 5.3.7.0 (2011/07/01) フォルãƒ?�«アクセスできなã�??合ã?、エラー
723 if( list == null ) {
724 System.err.println( file + " はアクセスできませんã€? );
725 return false;
726 }
727
728 for( int i=0; i<list.length; i++ ) {
729 deleteFiles( list[i] );
730 }
731 }
732 if( !file.delete() ) { return false; }
733 }
734 return true;
735 }
736
737 /**
738 * æŒ?®šされたãƒ?‚£レクトリを基点としたファイルå�?パスを含ã‚?のä¸?¦§を返しますã?
739 *
740 * @og.rev 4.3.6.6 (2009/05/15) 新規作æ?
741 * @og.rev 5.4.3.2 (2012/01/06) 引数isCopy追åŠ?
742 *
743 * @param dir 基点となるディレクトリ
744 * @param sort ファイル名でソートするか
745 * @param list ファイル名ä¸?¦§をæ?納するList
746 * @param isCopy コピã?中ファイルを除外するか [true:含ã‚?false:除外]
747 */
748 public static void getFileList( final File dir, final boolean sort, final List<String> list, boolean isCopy ) {
749 if( list == null ) { return; }
750 if( dir.isFile() ) {
751 // コピã?中判定ã?renameで行う
752 if( !isCopy && !dir.renameTo( dir ) ){
753 return;
754 }
755 else{
756 list.add( dir.getAbsolutePath() );
757 }
758 }
759 else if( dir.isDirectory() ) {
760 File[] files = dir.listFiles();
761 for( int i=0; i<files.length; i++ ) {
762 getFileList( files[i], sort, list, isCopy );
763 }
764 }
765 if( sort ) {
766 Collections.sort( list );
767 }
768 }
769
770 /**
771 * æŒ?®šされたãƒ?‚£レクトリを基点としたファイルå�?パスを含ã‚?のä¸?¦§を返しますã?
772 * 互換性のため、コピã?中ファイルも含みますã?
773 *
774 * @og.rev 5.4.3.2 (2012/01/06) コピã?中対応ã?ため引数?”つを作æ?する
775 *
776 * @param dir 基点となるディレクトリ
777 * @param sort ファイル名でソートするか
778 * @param list ファイル名ä¸?¦§をæ?納するList
779 */
780 public static void getFileList( final File dir, final boolean sort, final List<String> list ) {
781 getFileList( dir, sort, list, true );
782 }
783
784 /**
785 * æŒ?®šされたファイルå�?パスを含ã‚?から、パスも拡張子もなã�?ƒ•ァイル名を返しますã?
786 *
787 * @og.rev 5.6.1.2 (2013/02/22) 新規作æ?
788 *
789 * @param filename ファイルå�?パスを含ã‚?
790 * @return パスもã?拡張子もなã�?ƒ•ァイルå�?
791 */
792 public static String getBaseName( final String filename ) {
793
794 if (filename == null) {
795 return null;
796 }
797
798 // セパレータの位置を取得ã?
799 int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
800 int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
801 int lastSepPos = Math.max( lastUnixPos , lastWindowsPos );
802
803 // 拡張子ã?位置を取得ã?
804 int extPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
805 if( lastSepPos > extPos ) { extPos = -1; } // 念のため、最後ã?セパレータより前にある拡張子ã?区åˆ?‚Šæ–?—ã?無効ã€?
806
807 if( extPos < 0 ) {
808 // SEPARATOR がなければ、lastSepPos + 1 = 0 となりã?先é?から取得できるã€?
809 return filename.substring( lastSepPos + 1 );
810 } else {
811 return filename.substring( lastSepPos + 1 , extPos );
812 }
813 }
814
815 /**
816 * PrintWriter を継承した、System.out/System.err 用のクラスを定義しますã?
817 *
818 * 通常の、new PrintWriter( OutputStream ) で、求めるã?と、ほとんど同様ã?
819 * 処ç�?‚’行いますã?
820 * ただ、close() メソãƒ?ƒ‰が呼ばれてもã?何もしませんã€?
821 *
822 */
823 private static final class NonClosePrintWriter extends PrintWriter {
824 /**
825 * コンストラクター
826 *
827 * new PrintWriter( OutputStream ) を行いますã?
828 *
829 * @param out OutputStream
830 */
831 public NonClosePrintWriter( final OutputStream out ) {
832 super( out );
833 }
834
835 /**
836 * close() メソãƒ?ƒ‰をオーバã?ライドしますã?
837 *
838 * 何もしませんã€?
839 *
840 */
841 public void close() {
842 // ここでは処ç�?‚’行いませんã€?
843 }
844 }
845
846 /**
847 * PrintWriter を継承した、JspWriterなどの Writer 用のクラスを定義しますã?
848 *
849 * 例えば、JspWriterなどの JSP/Servlet等ã?フレーãƒ?ƒ¯ークで使用されã‚?
850 * Writer では、flush ã‚?close 処ç�??、フレーãƒ?ƒ¯ークå†?�§行われますã?
851 * そã?場合ã?通常のファイルと同じ用に、flush ã‚?close をアプリケーション側で
852 * 行うと、å?部処ç�?š„に不整合が発生したり、最悪の場合エラーになりますã?
853 * こã?クラスは、単にã€??常の、new PrintWriter( Writer ) で、求めるã?とã€?
854 * ほとんど同様ã?処ç�?‚’行いますã?
855 * ただ、close() と flush() メソãƒ?ƒ‰が呼ばれてもã?何もしませんã€?
856 *
857 */
858 private static final class NonFlushPrintWriter extends PrintWriter {
859 /**
860 * コンストラクター
861 *
862 * new PrintWriter( Writer ) を行いますã?
863 *
864 * @param writer Writer
865 */
866 public NonFlushPrintWriter( final Writer writer ) {
867 super( writer );
868 }
869
870 /**
871 * close() メソãƒ?ƒ‰をオーバã?ライドしますã?
872 *
873 * 何もしませんã€?
874 *
875 */
876 public void close() {
877 // ここでは処ç�?‚’行いませんã€?
878 }
879
880 /**
881 * flush() メソãƒ?ƒ‰をオーバã?ライドしますã?
882 *
883 * 何もしませんã€?
884 *
885 */
886 public void flush() {
887 // ここでは処ç�?‚’行いませんã€?
888 }
889 }
890
891 /**
892 * ファイルをコピã?しますã?
893 *
894 * 引数に <file1> <file2> [<encode1> <encode2>] を指定しますã?
895 * file1 を読み込み、file2 にコピã?しますã?コピã?前に、file2 は、file2_backup にコピã?しますã?
896 * file1 がã?ãƒ?‚£レクトリの場合ã?、ディレクトリごとコピã?しますã?
897 * encode1、encode2 を指定すると、エンコード変換しながらコピã?になりますã?
898 * こã?場合ã?、ファイル同士のコピã?のみになりますã?
899 *
900 * @og.rev 4.0.0.0 (2007/11/28) メソãƒ?ƒ‰の戻りå?をチェãƒ?‚¯しますã?
901 * @og.rev 5.1.6.0 (2010/05/01) 引数の並びé ??処ç�?‚’変更しますã?
902 *
903 * @param args 引数配å? file1 file2 [encode1 encode2]
904 */
905 public static void main( final String[] args ) throws Throwable {
906 if( args.length != 2 && args.length != 4 ) {
907 LogWriter.log("Usage: java FileUtil <file1> <file2> [<encode1> <encode2>]" );
908 return ;
909 }
910
911 File file1 = new File( args[0] );
912 File file2 = new File( args[1] );
913
914 File tempFile = new File( args[1] + "_backup" );
915
916 if( args.length < 3 ) {
917 if( file1.isDirectory() ) {
918 FileUtil.copyDirectry( file1, file2, true );
919 }
920 else {
921 FileUtil.copy( file2,tempFile );
922 FileUtil.copy( file1,file2, true );
923 }
924 }
925 else {
926 String encode1 = args[2];
927 String encode2 = args[3];
928
929 FileUtil.copy( file2,tempFile );
930
931 BufferedReader reader = FileUtil.getBufferedReader( file1 ,encode1 );
932 PrintWriter writer = FileUtil.getPrintWriter( file2 ,encode2 );
933
934 try {
935 String line1;
936 while((line1 = reader.readLine()) != null) {
937 writer.println( line1 );
938 }
939 }
940 finally {
941 Closer.ioClose( reader ) ;
942 Closer.ioClose( writer ) ;
943 }
944 }
945 }
946 }