文字ストリーム

バージョン1.1のJava Development Kitから、java.ioパッケージで文字ストリームがサポートされるようになりました。

1.1より前のJDKの標準入出力機能では、InputStreamおよびOutputStreamクラスとこれらのサブクラスを使用するバイト・ストリームのみがサポートされていました。文字ストリームはバイト・ストリームと似ていますが、文字ストリームには、8ビット単位のバイトではなく16ビットのUnicode文字が含まれます。文字ストリームは、ReaderクラスとWriterクラス、およびこれらのサブクラスによって実装されます。ReaderおよびWriterでは、InputStreamおよびOutputStreamと基本的に同じ操作がサポートされます。ただし、バイト・ストリームのメソッドがバイトまたはバイト配列を操作するのに対し、文字ストリームのメソッドは、文字、文字配列、または文字列を操作する点が異なります。

バイト・ストリームで利用できる機能のほとんどは、文字ストリームでも利用できます。文字ストリーム・クラスとバイト・ストリームの名前にも同じことが言えます。文字ストリーム・クラスの接頭辞には、通常は対応するバイトストリーム・クラスの名前と同じものが使用されています。たとえば、PushbackReaderクラスでは、PushbackInputStreamクラスからバイト・ストリームに提供される機能が文字ストリームにも提供されます。

文字ストリームを使用する理由

文字ストリームを使用する主な利点は、特定の文字エンコーディングに依存しないプログラムを簡単に作成できるため、国際化が簡単になることです。

Javaでは、文字列がUnicodeで格納されます。Unicodeは国際標準の文字エンコーディングで、各国のほとんどの記述用言語を表すことができます。ただし、ユーザーが読むことのできる標準的なテキスト・ファイルでは、UnicodeまたはASCIIに関連しないエンコーディングが使用されていることがあります。エンコーディングには、様々な種類があります。文字ストリーム機能では、バイト・ストリームおよび文字ストリーム間の変換を行う2つのクラスが提供されます。このため、エンコーディング処理の複雑さが解消されています。InputStreamReaderクラスでは、バイト入力ストリームからバイトを読み取り、指定されたエンコーディングに応じて文字に変換する文字入力ストリームが実装されます。同様に、OutputStreamWriterクラスでは、指定されたエンコーディングに応じて文字をバイトに変換し、バイト出力ストリームに書き込む文字出力ストリームが実装されます。

文字ストリームの2つ目の利点は、バイト・ストリームよりも効率的なことです。Java独自のバイト・ストリームのほとんどの実装では、読み込みおよび書込み操作が一度に1バイト単位で行われます。これに対し、文字ストリーム・クラスでは、読み込みおよび書込み操作が一度に1バッファ単位で行われます。文字ストリーム・クラスでは、この利点とより効率的なロック方式によって、エンコーディング変換によって追加されたオーバーヘッドが多くの場合相殺されます。

APIの概要

文字ストリーム・クラスは、java.ioパッケージの既存のバイトストリーム・クラスに対応するように設計されています。すでに説明したように、各文字ストリーム・クラス名は、ReaderまたはWriterで終わります。また、対応するバイトストリーム・クラスが存在する場合は、通常、そのバイトストリーム・クラスと同じ接頭辞になります。次の表は、新しいクラス名の一覧です。左の列のインデントは、サブクラスの関係を示しています。
文字ストリーム・クラス 説明 対応するバイト・クラス
 
Reader 文字入力ストリームの抽象クラス InputStream
    BufferedReader 入力をバッファに格納し、行を構文解析する BufferedInputStream
        LineNumberReader     行番号を追跡する LineNumberInputStream
    CharArrayReader 文字配列から読み込む ByteArrayInputStream
    InputStreamReader バイト・ストリームを文字ストリームに変換する (なし)
        FileReader ファイルのバイトを文字ストリームに変換する     FileInputStream
    FilterReader フィルタをかけられた文字入力の抽象クラス FilterInputStream
        PushbackReader 文字をプッシュ・バックする PushbackInputStream
    PipedReader PipedWriterから読み込む PipedInputStream
    StringReader Stringから読み込む StringBufferInputStream
 
Writer 文字出力ストリームの抽象クラス OutputStream
    BufferedWriter 出力をバッファに格納し、プラットフォームの行区切り文字を使用する BufferedOutputStream
    CharArrayWriter 文字配列に書き込む ByteArrayOutputStream
    FilterWriter フィルタをかけられた文字出力の抽象クラス FilterOutputStream
    OutputStreamWriter 文字ストリームをバイト・ストリームに変換する (なし)
        FileWriter 文字ストリームをバイト・ファイルに変換する FileOutputStream
    PrintWriter 値およびオブジェクトをWriterに出力する PrintStream
    PipedWriter PipedReaderに書き込む PipedOutputStream
    StringWriter Stringに書き込む (なし)

関連する変更

PrintStream

PrintStreamクラスは、プラットフォームのデフォルトの文字エンコーディングおよびプラットフォームのデフォルトの行末記号を使用するように変更されました。このため、各PrintStreamには、OutputStreamWriterが組み込まれました。このライターを介してすべての文字が渡され、出力用のバイトが生成されます。printlnメソッドでは、プラットフォームのデフォルトの行末記号が使用されます。この行末記号は、システム・プロパティline.separatorによって定義されますが、必ずしも1つの改行文字(「\n」)である必要はありません。既存のwriteメソッドによって出力されたバイトおよびバイト配列は、ライター経由では渡されません。

PrintStreamクラスの変更により、ASCII以外のローカル・エンコーディングが使用されているプラットフォームでJavaプログラムを記述している場合、System.outおよびSystem.errが使いやすくなりました。つまり、PrintStreamは、主にデバッグでの使用と既存のコードとの互換性のために提供されています。テキスト出力を生成するコードでは、新しいPrintWriterクラスを使用してください。このクラスでは、文字エンコーディングを指定することも、デフォルトのエンコーディングを受け入れることもできます。PrintWriterクラスでは、OutputStreamオブジェクトをとるコンストラクタが提供され、デフォルトのエンコーディングを使用する中間OutputStreamWriterオブジェクトが作成されます。

その他のクラス

次のコンストラクタおよびメソッドでは、バイトと文字が適切に変換されないため、非推奨になりました。

String   DataInputStream.readLine()
InputStream   Runtime.getLocalizedInputStream(InputStream)
OutputStream   Runtime.getLocalizedOutputStream(OutputStream)
  StreamTokenizer(InputStream)
   String(byte ascii[], int hibyte, int offset, int count)
   String(byte ascii[], int hibyte)
void   String.getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)

次のコンストラクタおよびメソッドが追加されました。

  StreamTokenizer(Reader)
byte[]   String.getBytes()
void   Throwable.printStackTrace(PrintWriter)

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.