2-4-1: ストリームとそのクラス


・ まず java.io の主要な部分を占める入出力を取り扱うストリームのクラス群について 解説しましょう。 初めて java.ioパッケージを利用する時に一番驚かされるのは、 おそらくこれらのクラスの種類の多さでしょう。 しかし幸いなことに、それらを全て個別に見ていく必要はありません。 その基本にある「ストリーム」の考え方と、 入出力処理の基本パターンを理解することがポイントです。
 「ストリーム(Stream)」は決して難解な概念ではありません。 しかし、何を指しているのか具体的にわかりにくいかもしれません。 ストリームとして実際に取り扱われるものを挙げた方が、 おそらく理解は早いと思います。 それらは、ファイル、ディスプレイやキーボードなどの入力デバイス、 ネットワークの回線などです。 それらの入出力の「流れ」を抽象化して表現したものがストリームなのです。


さまざまなスタイルの入出力を「ストリーム」として抽象化する

 では、ストリームの考え方を敢えて導入する利点はどこにあるのでしょうか? 入出力のプログラムを、ファイルならばファイル、 キーボードならキーボードというように、 対象となるものごとに別個に記述する方法もあり得ます。 しかし、それは明らかに効率の良い方法とは言えません。 作成されたプログラムはハードウェアに強く依存しているため、 他の目的に転用することが困難です。 プログラマは、 多くの予備知識を学ばなければプログラミングを開始することができません。 そして新しいデバイスが登場するごとに、 新たにプログラムをゼロから作り直すことになります。 これに比べて「ストリームへの入出力」のスタイルで記述されたプログラムは、 より汎用性が高くなります。 システムやハードウェアに依存しない形でプログラムを記述することが可能だからです。 プログラマの負担が大幅に軽減される点も重要でしょう。
 ストリームのアイディア自体はオブジェクト指向とは独立に生み出されたものです。 しかし上のような事情は、 抽象クラスやインターフェイスの働きと共通するものがあります。 実際、この後で紹介していく java.ioのストリームのクラス群は、 共通する抽象クラスをスーパークラスとして持っています。 そのおかげで多数のクラスが存在しても、 入出力の基本処理はすべて共通のパターンで行うことができるわけです。
 なお、古典的なストリームでは データの流れは単純なバイト列として取り扱われます。 ただし、この後紹介する java.ioのストリームのクラスでは、 それが拡張されています。 バイト単位の場合と、Javaの char型のデータ(2バイト)単位の場合がありますが、 考え方の基本に変わりはありません。

・ ストリームのクラスは java.ioに含まれるものだけで 40個以上あります。 ここではその基本的なものを紹介しますが、 それでも何らかの基準で分類する必要がありそうです。
 まずストリームのクラスは、 入力用のものと出力用のものに大きく分けられるでしょう。 この他に、もう一つ重要な区別があります。 それはストリームのデータの単位によるものです。 Javaでは char型が国際化対応のために2バイトのサイズになっています。 したがってテキストの入出力は char単位のストリームを用いて処理します。 それに対してバイナリのデータとして入出力を行う場合には、 従来の byte単位のストリームが用いられます。 つまり、 ストリームのクラスは大きく4つのグループに分類することができるわけです。 それぞれのストリームのグループは共通の抽象クラスをスーパークラスとします。

ストリームを代表する抽象クラス
入力用出力用
byte単位InputStreamOutputStream
char単位ReaderWriter

 それぞれのグループには、 入出力の目的や対象に合わせてほぼ10個ずつのクラスが提供されています。 たとえばファイルの入出力に関連して、テキストの入力用の FileReader、 テキストの出力用の FileWriter、バイナリデータの入力用の FileInputStream、 バイナリデータの出力用の FileOutputStreamという4個のクラスが存在します。 ただし、すべてのクラスが4個1組になっているわけではありません。 たとえば、原始型のデータの入出力のストリームを提供する DataInputStream、 DataOutputStream に対応する Reader や Writerは存在しません。 ストリームからの「先読み」の機能を提供する PushbackInputStream、 PushbackReaderに対応する OutputStreamや Writerは存在しません。

InputStream とそのサブクラスReader とそのサブクラス
InputStream
ByteArrayInputStream
BufferedInputStream
DataInputStream
StringBufferInputStream
FilterInputStream
PipedInputStream
FileInputStream
LineNumberInputStream
SequenceInputStream
PushbackInputStream
ObjectInputStream
Reader
InputStreamReader
CharArrayReader
BufferedReader
StringReader
FilterReader
PipedReader
FileReader
LineNumberReader
PushbackReader

OutputStream とそのサブクラスWriter とそのサブクラス
OutputStream
PrintStream
ByteArrayOutputStream
BufferedOutputStream
DataOutputStream
FilterOutputStream
PipedOutputStream
FileOutputStream
ObjectOutputStream
Writer
OutputStreamWriter
PrintWriter
CharArrayWriter
BufferedWriter
StringWriter
FilterWriter
PipedWriter
FileWriter