このバージョン以前では、標準 I/O 機能は InputStream および OutputStream クラスとそのサブクラスを経由して、バイトストリームだけをサポートしていました。文字ストリームはバイトストリームのようなものですが、8 ビットバイトでなく 16 ビット Unicode{tm} 文字を含んでいます。これらは Reader および Writer クラスとそのサブクラスによって実装されます。Reader および Writer は、 InputStream および OutputStream と同様な操作を基本的にサポートします。異なる点は、バイトストリームメソッドがバイトまたはバイト配列上で動作するのに対して、文字ストリームは文字、文字配列、文字列上で動作するという点です。
バイトストリームで使用可能なほとんどの機能は、また文字ストリームでも提供されます。これは各文字ストリームクラスの名前に反映されており、この前置は、通常対応するバイトストリームクラスと共有されています。例えば、PushbackReader というクラスがあり、これはバイトストリームでPushbackInputStreamが提供する機能と同じものを、文字ストリームでも提供します。
Java は、国際標準文字エンコーディングである Unicode{tm} に文字列を格納します。これはほとんど世界中の記述言語を表すことができます。しかし、代表的なユーザが読むテキストファイルは、 Unicode{tm} または ASCII にさえも必ずしも関係しないエンコーディングを使用します。そして、このようなエンコーディングは多数あります。文字ストリームは、バイトストリームと文字ストリームの間の架け橋として機能する 2 つのクラスを提供して、これらのエンコーディングを取扱う複雑さを覆い隠します。InputStreamReader クラスは文字入力ストリームを実装し、これはバイト入力ストリームからバイトを読み込み、そして指定されたエンコーディングに従って文字に変換します。同様に、OutputStreamWriter クラスは文字出力ストリームを実装し、これは指定されたエンコーディングに従って文字をバイトに変換し、そしてバイト出力ストリームに書き込みます。
文字ストリームの第 2 の利点は、潜在的にバイトストリームよりかなり効率的であることです。Java の当初のバイトストリームの実装の多くは、バイト単位の読み書き操作を指向しています。文字ストリームクラスは対照的に、バッファ単位の読み書き操作を指向します。この差異はもっと効率的なロック方式と組み合わされて、文字ストリームクラスが多くのケースでエンコーディング変換の追加されたオーバーヘッドを補完できるようにします。
| 文字ストリームクラス | 内容説明 | 対応するバイトクラス |
| Reader | 文字入力ストリームの abstract クラス | InputStream |
| BufferedReader | 入力のバッファリング、行の分解 | BufferedInputStream |
| LineNumberReader   | 行番号の追跡 | LineNumberInputStream |
| CharArrayReader | 文字配列の読み込み | ByteArrayInputStream |
| InputStreamReader | バイトストリームの文字ストリームへの変換 | (なし) |
| FileReader | ファイルのバイトを文字ストリームに変換   | FileInputStream |
| FilterReader | フィルタをかけられた文字入力の abstract クラス | FilterInputStream |
| PushbackReader | 文字の押し戻しの許可 | PushbackInputStream |
| PipedReader | PipedWriter の読み込み | PipedInputStream |
| StringReader | String の読み込み | StringBufferInputStream |
| Writer | 文字出力ストリームの abstract クラス | OutputStream |
| BufferedWriter | 出力のバッファリング、プラットフォームの行区切り文字の使用 | BufferedOutputStream |
| CharArrayWriter | 文字配列への書き込み | ByteArrayOutputStream |
| FilterWriter | フィルタをかけられた文字出力の abstract クラス | FilterOutputStream |
| OutputStreamWriter | 文字ストリームのバイトストリームへの変換 | (なし) |
| FileWriter | 文字ストリームのバイトファイルへの変換 | FileOutputStream |
| PrintWriter | Writer への値とオブジェクトの印刷 | PrintStream |
| PipedWriter | PipedReader への書き込み | PipedOutputStream |
| StringWriter | String への書き込み | (なし) |
PrintStream クラスを変更する主な動機は、そうすることで、 Java プログラムを ASCII 以外のローカルエンコーディングのプラットフォーム上で書く人々にとって、System.out および System.err がより有用になるからです。換言すれば、PrintStream はデバッグでの使用および既存のコードとの互換性のために主に提供されます。そのため、次の 2 つの構築子は推奨されません:
| PrintStream(OutputStream) | |
| PrintStream(OutputStream, boolean) |
クラス全体より構築子を推奨しないことによって、System.out および System.err をそのまま使用していてコンパイルしても、推奨しない由の警告が出なくなります。こうして、Java を丁度学んでいるプログラマ、またはデバッグの目的で System.err.println 呼び出しを挿入しようとしているプログラマは、このような警告に悩まされなくなります。他方、明示的に PrintStream を構築するコードを書いているプログラマは、そのコードをコンパイルする際、推奨しない由の警告を見ることになります。テキスト出力を生成するコードは新しい PrintWriter クラスを使用する必要があり、このクラスは文字エンコーディングの指定またはデフォルトエンコーディングの受け入れを許します。便宜のために、PrintWriter クラスは OutputStream オブジェクトを取り上げ、デフォルトエンコーディングを使用する即座の OutputStreamWriter オブジェクトを作成する構築子を提供します。
いくつかの既存のクラスに対して小さな変更が行われました。次の構築子とメソッドは、バイトと文字の変換を正しく行わないので、推奨されません:
最後に、次の構築子とメソッドが追加されました:
| StreamTokenizer(Reader) | |
| byte[] | String.getBytes() |
| void | Throwable.printStackTrace(PrintWriter) |
| コメントは java-io@java.sun.com 宛てに送ってください。 | Mark Reinhold / 4 February 1997 |