ファイルからの入力とファイルへの出力は次のようにします。
import java.io.*; class Test { public static void main(String args[]) { try { InputStream input = new FileInputStream("foo.txt"); // 入力ファイルを開く OutputStream output = new FileOutputStream("bar.txt"); // 出力ファイルを開く int c; while ((c = input.read()) != -1) // 入力 output.write(c); // 出力 input.close(); // 入力ファイルを閉じる output.close(); // 出力ファイルを閉じる } catch (IOException e) { // 入出力エラーをつかまえる System.err.println(e); // エラーメッセージ出力 System.exit(1); // 終了コード 1 で終了する } } }
これは,foo.txt というファイルを読んで, 内容をそのまま bar.txt というファイルに書き出すプログラムです。
もし foo.txt が存在しないと, 15行目の System.err.println(e); が
java.io.FileNotFoundException: foo.txtと出力して止まってしまいます。 また,もし bar.txt があると,それに上書きしてしまいますので, 気をつけてください。
上のプログラムで,
InputStream input; input = new FileInputStream("foo.txt");としていますね。これは本当は
FileInputStream input; input = new FileInputStream("foo.txt");と書くべきだと思われるかもしれません。もちろんそう書いてもいいのですが, FileInputStream は InputStream の子クラスですので, より一般的な InputStream 型の変数 input を作って, それに FileInputStream クラスのインスタンスを代入しても かまわないのです。ただしこれは, 親クラスが子クラスと同じ名前・引数のメソッドを持つ場合だけです。 子クラスの親クラスにない名前のメソッドを使いたい場合は, ちゃんと子クラスの型の変数に代入しなければなりません。
上のプログラムは,ディスクから1文字(1バイト)ずつ 読み書きしていますので,あまり能率的ではありません。 上の
InputStream input = new FileInputStream("foo.txt"); // 入力ファイルを開く OutputStream output = new FileOutputStream("bar.txt"); // 出力ファイルを開くのところを
InputStream input = new BufferedInputStream( new FileInputStream("foo.txt")); OutputStream output = new BufferedOutputStream( new FileOutputStream("bar.txt"));とするだけで,ずいぶんプログラムの実行速度が上がります。 これはバッファリングの効果です。
バッファ(buffer)とは一般に「緩衝(かんしょう)装置」つまり 二つのものの間にはさまって衝撃を和らげるもののことです。
ファイルからの入力の場合は, 1バイトずつディスクから読むと時間がかかるので, 一度にたとえば512バイト読み込んでメモリの一部(バッファ)に保存しておき, 2度目からは実際に読むのではなくメモリからコピーしてくることを意味します。
ファイルへの出力も同様で, 最初は実際に書き込まずバッファに保存しておき, たとえば512バイトになると一気に書き出します。
バッファを使うことをバッファリング(buffering)するともいいます。
バッファリングしているときは,最後の文字を書き出したつもりでも, 実際には端数分がメモリに残っています。 この端数分は, 出力ファイルをクローズした(閉じた)時点でディスクに書き込まれます。 つまり,output.close() を実行した時点で書き込まれます。 クローズを忘れると,ファイルが全部書きおわらないうちに終了して しまうことがありますので,必ずオープンしたらクローズする習慣をつけましょう。
上のプログラムをさらに
DataInputStream input = new DataInputStream( new BufferedInputStream( new FileInputStream("foo.txt"))); PrintStream output = new PrintStream( new BufferedOutputStream( new FileOutputStream("bar.txt")));とすると,入力では readLine(), 出力では println() のような便利なメソッドが使えるようになります。 たとえば
String s; while ((s = input.readLine()) != null) output.println(s);のようなことができます。 readLine() は,ファイルの終わりまで読み尽くした後では, null という特別な値を返します。これが返ってきたら, 繰返しを終了します。