★JAVAで作成1(ioパッケージ利用)
JAVAでは、2通りの方法でファイルコピーを行えます。今回はその内の1つである、ioパッケージ利用編です。
JAVAのバージョンは1.4を使用します。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class CopyByJava1 { public void execute(String src, String dest) throws IOException { int buffer_size = 2048; byte[] buffer = new byte[buffer_size]; InputStream in = null; OutputStream out = null; try { // ファイルのオープン & ストリームのバッファサイズ指定 in = new BufferedInputStream(new FileInputStream(src), buffer_size); out = new BufferedOutputStream(new FileOutputStream(dest), buffer_size); // コピー実行 int readsize; while((readsize = in.read(buffer)) != -1) { out.write(buffer, 0, readsize); } } finally { // ファイルクローズ try { if(in != null) { in.close(); } } catch(IOException e) { } try { if(out != null) { out.close(); } } catch(IOException e) { } } } public static void main(String[] args) { if(args.length < 2) { System.out.println("java CopyByJava1 [コピー元ファイルパス] [コピー先ファイルパス]"); return; } else if(args[0].equals(args[1])) { System.out.println("コピー元とコピー先が同じです。"); return; } long start = System.currentTimeMillis(); try { new CopyByJava1().execute(args[0], args[1]); } catch(IOException e) { e.printStackTrace(); return; } long end = System.currentTimeMillis(); System.out.println((end - start)/1000.0 + " 秒経過"); } } |
前回と同じく、以下の項目をちょっとだけ見てみましょう。
- クラス
- 例外処理機構
- リソースの解放
▽クラス
クラスが登場する点はC++と同じです。但し、自作しているCopyByJava1クラスがあります。
JAVAは単独でメソッド(C/C++における関数のこと)が存在出来ません。
必ず、クラスのメンバーとしてメソッドが存在します。このルールは mainメソッドにも当てはまる為、最低でも1つのクラスが必要になります。
▽例外処理機構
try-catchは同じです。但し、JAVAではfinallyが存在します。
tryブロックに処理が入った場合、例外の発生有無に関らず、必ずfinallyブロックを通ります。
処理が成功・失敗のいずれであっても、行う処理が有る場合にfinallyを用います。
▽リソースの解放
JAVAではC++と同じくクラスが登場する事は、先ほど説明しました。
では何故、C++で必要の無かったファイルのクローズを行っているのでしょう?
JAVAにはデストラクタが無いのでしょうか?それともFileInputStreamやFileOutputStreamクラスのデストラクタでは自動的にファイルをクローズしてくれないのでしょうか?
答えは否です。デストラクタに相当する物(finalizeメソッド)も有りますし、該当クラスのfinalizeメソッドでファイルのクローズも行われます。
JAVAでは、C/C++に無い機能としてガーベッジコレクションがあります。これにより、動的に確保したメモリ(上に構築されたクラス)の解放はプログラマが意識する必要が無いので、プログラマとしては非常に助かります。
しかし、ファイルディスクプリタやソケットなどの非メモリ・リソースはこの対象外であり、これらは(finalizeメソッドの中で処理すれば)メモリ回収のついでとして解
放されるだけです。
つまり、メモリ・リソースが潤沢に存在しても、非メモリ・リソースの不足が発生する可能性があります。この様な状態を極力起さない為には、プログラマが責任を持っ
て非メモリ・リソースの解放を行う事が必要になります。(その為に、先のfinallyを利用してファイルクローズを行っています)
次回は、もう1つのJAVAである、nioパッケージ利用編です。