バイトストリームと文字ストリーム
「第2回 EclipseでJavaの入出力を理解する」でストリームの基本については解説しましたが、バイトストリームと文字ストリームについては説明しませんでした。Javaでデータ入出力を行うプログラムを作成する場合は、8ビットというバイト単位での入出力をするバイトストリームを使うか、基本的に16ビットUnicode文字という文字単位での入出力をする文字ストリームを使うか決めてから、使用するクラスを決めることを基本方針とするのがよいでしょう。なお、java.ioパッケージでは、バイトストリームを扱うクラスにはInputStream、OutputStreamといった名前が使われています。文字ストリームを扱うクラスにはReader、Writerといった名前が使われています。
さて、「第6回 Eclipseで文字符号化の理解を深める」で説明したように、文字についてはどのような文字符号化を利用しているかによって処理が変わってくるため、単純なバイトデータの操作で処理をするのは大変です。このため、対象となるデータが文字の場合に簡単に処理ができるよう、用途を特化した文字ストリームが用意されています。せっかくあるのですから、文字データを扱う場合はこれを使用した方がいいでしょう。ただし、文字データを扱っていても場合によってはバイトデータとして扱いたいときもありますから、その場合はバイトストリームを使うこともあります。
データをファイルへ入出力するには、バイトストリームのjava.io.InputStreamクラス、java.io.OutputStreamクラスをそれぞれ継承するjava.io.DataInputStreamクラスとjava.io.DataOutputStreamクラスを使います。エラー処理と例外処理を考えずに一連の処理の流れをコーディングすると以下のようになります。
DataOutputStream dos = new DataOutputStream( new FileOutputStream(new File("sample1.txt"))); dos.writeBoolean(true); dos.writeByte(1); dos.writeChar('A'); dos.flush(); dos.close(); DataInputStream dis = new DataInputStream( new FileInputStream(new File("sample1.txt"))); System.out.println(dis.readBoolean()); System.out.println(dis.readByte()); System.out.println(dis.readChar()); dis.close(); System.out.println("");
このようにDataOutputStreamクラスには各プリミティブデータの型に応じたwriteBooleanメソッドやwriteByteメソッドといった書き出しメソッドが用意されています。また、DataInputStreamクラスには、同様にreadBooleanメソッドといった読み込みメソッドが用意されています。
どんな順番でどんなデータ型の値が書き込まれるかというフォーマットを決めておけば、ファイルの中にデータを保存したり、後で読み込んで利用したりすることができるようになります。ここではデータフォーマットを「boolean値」「byte値」「char値」の順で並べています(完全なプログラムは730.javaをダウンロードして参考にしてください)。
なお、実際にファイルの中に保存されているバイト値を表示するためには次のようにします。ここで、データ型を考えると、バイトデータをint型の変数へ代入して、コンソール出力時にbyte型へ型変換(キャスト)をしていますが、文字ストリームを利用したときと同じ理由でこのようになっています。
InputStream is = new FileInputStream(new File("sample1.txt")); int b; while ((b = is.read()) != -1) { System.out.println((byte)b); } is.close();
以下の実行結果を見て分かるように、指定した「boolean値」「byte値」「char値」の順で並ぶデータフォーマットで書き込み、読み込みができています。また、どんなバイト値で保存されているかを確認するための出力を見ても、正しく保存されているのが分かります。
次に、ストリームを操作するプログラムを作成していると、例えばデータをバッファリングしてデータ入出力の効率を良くする機能などが欲しくなってきます。こういった拡張機能を実現するクラスとして、java.ioパッケージにはBufferedInputStreamやBufferedReaderのようなBufferedで名前が始まるクラスが用意されています。これらのクラスを使うと簡単にバッファリング機能付きのオブジェクトを用意することができますが、ストリームを表現するクラスはコンストラクタにストリームオブジェクトを引数で指定できるようになっているため、使いたい拡張機能を簡単に組み合わせることができます。
DataOutputStreamやDataInputStreamのデータ入出力機能をバッファ機能と組み合わせて使いたい場合には次のようにします。ほかの処理は変更する必要がありません(完全なプログラムはSample740.javaをダウンロードして参考にしてください)。
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream(new File("sample1.txt")))); DataInputStream dis = new DataInputStream( new BufferedInputStream( new FileInputStream(new File("sample1.txt"))));
このほかにも、java.io.LineNumberReaderクラス、java.io.PushbackReaderクラスなど有用な拡張機能を提供するクラスがあります。APIリファレンスを参考にして、組み合わせて使えるようになりましょう
Copyright © ITmedia, Inc. All Rights Reserved.