このページを正しく表示するには、ブラウザでJavaScriptを有効にする必要があります。
コース: 重要なクラス
レッスン: 基本的なI/O
セクション: I/Oストリーム
文字ストリーム
ホームページ > 重要なクラス > 基本的なI/O

文字ストリーム

Javaプラットフォームでは、文字値の保存にUnicode規則を使用します。 文字ストリームI/Oによって、内部のUnicode形式とローカル文字セットとの変換が自動的に行われます。 欧米のロケールでは、ローカル文字セットは通常、ASCII 8ビットのスーパーセットです。

ほとんどのアプリケーションでは、文字ストリームによるI/Oはバイト・ストリームによるI/Oと同じくらい単純です。 ストリーム・クラスを使用した入出力では、ローカル文字セットとの変換は自動的に行われます。 バイト・ストリームの代わりに文字ストリームを使用するプログラムは、自動的にローカル文字セットに適応し、国際化に対応します。そのため、プログラマは余分な労力を費やさずにすみます。

国際化が急務でない場合は、文字セットの問題に注意を払わずに、単に文字ストリーム・クラスを使用できます。 後で国際化の対応が必要になった場合には、大幅な再コーディングなしでプログラムを適応させられます。 詳細は、『Internationalization』コースを参照してください。

文字ストリームの使用

すべての文字ストリーム・クラスは、ReaderまたはWriterの子孫クラスです。 バイト・ストリームの場合と同様に、ファイルI/Oに特化した文字ストリーム・クラスとしてFileReaderFileWriterがあります。 サンプル・プログラムのCopyCharactersでは、この2つのクラスを使用しています。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyCharacters {
    public static void main(String[] args) throws IOException {
        FileReader inputStream = null;
        FileWriter outputStream = null;

        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");

            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}
CopyCharactersCopyBytesとよく似ています。 もっとも重要な違いは、CopyCharactersでは、入出力にFileInputStreamFileOutputStreamではなくFileReaderFileWriterを使用している点です。 また、CopyBytesCopyCharactersはどちらも、読取りと書込みにint変数を使用しています。 ただし、CopyBytesではint変数はbyte値の最後の8ビットを保持するのに対して、CopyCharactersではint変数は文字値の最後の16ビットを保持する点が異なります。

バイト・ストリームを使用する文字ストリーム

文字ストリームは、しばしば、バイト・ストリームを包む"ラッパー"となります。 このような文字ストリームでは、文字とバイトとの変換を処理しながら、バイト・ストリームを使用して物理的なI/Oを実行します。 たとえば、FileReaderではFileInputStreamを使用し、FileWriterではFileOutputStreamを使用しています。

Javaには、バイトと文字との"橋渡し"の役目を持つ、2つの汎用的なストリームがあります。 InputStreamReaderOutputStreamWriterです。 ニーズに合った文字ストリーム・クラスがパッケージにない場合は、この2つのストリームを使用して文字ストリームを作成します。 『Custom Networking』コースのソケットに関するレッスンでは、Socketクラスによって提供されるバイト・ストリームから文字ストリームを作成する方法が説明されています。

行指向I/O

文字のI/Oは、通常は単一の語よりも大きな単位で実行されます。 一般的な単位は行、すなわち行区切り文字で終わる文字列です。 行区切り文字は、復帰とそれに続く改行("\r\n")、復帰のみ("\r")、または改行のみ("\n")です。 使用される可能性のあるすべての行区切り文字がサポートされているため、一般に使用されているあらゆるオペレーティング・システムで作成されたテキスト・ファイルをプログラムで読み取ることができます。

CopyCharactersの例を、行指向I/Oを使用するように修正してみましょう。このためには、これまでまだ登場していない、BufferedReaderPrintWriterという2つのクラスを使用する必要があります。 これらのクラスの詳細は、『バッファ・ストリーム』および『フォーマット』で確認します。 今のところは、行指向I/Oをサポートするクラスだという点のみに注目してください。

CopyLinesでは、BufferedReader.readLinePrintWriter.printlnを呼び出して、入力と出力を1行ずつ実行します。

import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;

public class CopyLines {
    public static void main(String[] args) throws IOException {
        BufferedReader inputStream = null;
        PrintWriter outputStream = null;

        try {
            inputStream = 
                new BufferedReader(new FileReader("xanadu.txt"));
            outputStream = 
                new PrintWriter(new FileWriter("characteroutput.txt"));

            String l;
            while ((l = inputStream.readLine()) != null) {
                outputStream.println(l);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}
readLineを呼び出すと、その行の1行分のテキストが返されます。 CopyLinesプログラムでは、各行の出力にprintlnを使用しています。printlnは、現在のオペレーティング・システムに合った行区切り文字を行末に追加します。 ここで追加される文字は、入力ファイルで使用されていた行区切り文字とは異なる可能性があります。

テキストの入力および出力を、文字や行という単位を超えて構造化する方法は数多くあります。 詳細は、『スキャンとフォーマット』を参照してください。


サンプル・プログラムで問題が発生した場合は、 『Compiling and Running the Examples: FAQs』を参照してください。
フィードバックをお寄せください。さまざまなご意見をお待ちしております。

前のページ: バイト・ストリーム
次のページ: バッファ・ストリーム