JavaA2Z

KAB-studio > プログラミング > JavaA2Z > Readerとは

Reader

日本語 読者
英語 reader
ふりがな りーだー
フリガナ リーダー

解説

J2SEに含まれるクラスのひとつ。パッケージも含めたクラス名java.io.Reader。
ストリームクラス。全ての文字入力ストリームクラススーパークラスである。
文字入力ストリームクラスの中では「入力元」に位置する。
対になる出力側のクラスWriterクラスである。
 
全ての文字入力ストリームクラススーパークラス
言い換えると、Readerクラスサブクラス文字入力ストリームクラスである、ということになる。
そういったスーパークラスとしての役目だけ持つため、このクラスを直接使用することはない。このクラスサブクラスを使用するか、もしくはサブクラスを作成して使用する。
そもそも抽象クラスであるため、インスタンスを作成することはできない。
基本的には、「入力元」となるクラスはこのReaderクラスサブクラスとし、「中継ぎ」となるクラスFilterReaderクラスサブクラスとする。
 
Readerクラスサブクラスを作成する場合、まず「本当の入力元」を用意する。「本当の入力元」は、char配列であったり、Stringクラスであったり、バイト入力ストリームであったりする。そういった「一に並べられたcharデータ」を「本当の入力元」とする。
他の文字入力ストリームクラスを「入力元」としてもいいが、それであればReaderクラスではなくFileReaderクラスサブクラスとした方がいいだろう。
 
Readerクラス抽象クラスであり、read()メソッド抽象メソッドであるため、サブクラスは必ずread()メソッドオーバーライドする必要がある。
オーバーライドするread()メソッド引数が「( char[], int, int )」のものである。read()メソッドオーバーロードされているが、他のオーバーロードされたメソッド抽象メソッドではないのでオーバーライドする必要はない。また、他のオーバーロードされたメソッドオーバーライドしなければ、「read( char[], int, int )メソッド呼び出してくれるため、このメソッドにのみ処理すればよい。
オーバーライドしたread()メソッドでは、「本当の入力元」から文字を取り出し、第1引数char配列にセットするよう実装する。そうすることで、渡された文字呼び出し元に返すことができる。
ただし、第2引数と第3引数は、第1引数配列の範囲を指定し、さらに第3引数は取得する文字数の指定もっている。対象の文字入力ストリームを超えて取得しないようにすること、配列要素数を超えて書き込まないようにすること、といったチェックが必要となる。
戻り値には取得した文字数を返す。read()メソッド呼び出した時点ですでに文字入力ストリームの末端に達していた場合には-1を返す。
  
read()メソッドの他にclose()メソッドオーバーライドする必要がある。close()メソッド抽象メソッドのためである。
close()メソッドは「本当の入力元」を閉じる処理をうよう実装する。特に、入力元がファイルソケットといった、最後に「閉じる」処理が必要な「本当の入力元」の場合には、必ずclose()メソッドオーバーライドし、使用時にはfinally呼び出すようにする。

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
import java.io.Reader;
import java.io.PushbackReader;
import java.io.IOException;

public class Sample
{
    public static void main( String[] args )
    {
        NormalReader normalReader = null;
        PushbackReader pushbackReader = null;
        try
        {
            // 「入力元」のNormalReaderクラスを用意します。
            normalReader = new NormalReader();

            // このクラスを対象とするPushbackReaderクラスを用意します。
            pushbackReader = new PushbackReader( normalReader );

            // つまり、

            // NormalReader
            // ↓
            // PushbackReader

            // という形で、文字入力ストリームクラスが連結したことになります。

            while( true )
            {
                // 1バイト取得します。
                int i = pushbackReader.read();
                if( i == -1 )
                {
                    // -1が返されてきたら終わりです。
                    break;
                }

                // 入力します。
                System.out.println( (char)i );
            }
            // あ
            // い
            // う
            // え
            // お

            // このように、pushbackReaderのread()メソッドを呼ぶと、
            // normalReaderのread()メソッドを呼び出します。
        }
        catch( IOException e )
        {
            // 読み込みに失敗した際に、read()メソッドが
            // IOException例外を投げます。
            e.printStackTrace();
        }
        finally
        {
            // 処理が終わったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( pushbackReader != null )
                {
                    pushbackReader.close();
                    // NormalReader#close()

                    // この結果から分かるとおり、stringReaderのclose()メソッドを
                    // 呼ぶと、「入力元」のnormalReaderのclose()メソッドも呼び
                    // 出されるので、本当は下のclose()メソッドを呼ぶ必要は
                    // ありません。でも必ずしも呼ばれるとは限らない
                    // (Javadocの仕様に書かれていない)ので呼んでおきましょう。
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            // 処理が終わったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( normalReader != null )
                {
                    normalReader.close();
                    // NormalReader#close()
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }
        }
    }
}

/**
*   NormalReaderクラス。
*   Readerクラスのサブクラスです。
*/
class NormalReader extends Reader
{
    // 対象の文字列。
    private String source = "あいうえお";
    // 現在の出力位置。
    private int pos = 0;

    /**
    *   read()メソッド。
    *   このクラスを利用する文字入力ストリームクラスの
    *   read()メソッドから呼び出されます。
    *   これをオーバーライドしておけば、他のオーバーロードされた
    *   read()メソッドが呼ばれても、最終的にこのメソッドが呼ばれるので
    *   適切に処理できます。
    */
    public int read( char[] cbuf, int off, int len) throws IOException
    {
        // 対象の文字数を超えていたら(つまり、文字入力ストリーム
        // の末端に達していたら)-1を返します。
        if( pos >= source.length() )
        {
            return -1;
        }

        // 第2引数から第3引数で指定された範囲まで、
        // 第1引数の配列にコピーして返します。
        // (注:実際には引数の整合性チェックや、最大文字数チェック等が
        // 必要です。でないとgetChars()メソッドがIndexOutOfBoundsException例外
        // を投げる可能性があります)
        source.getChars( pos, pos + len, cbuf, off );

        // 取り出した分だけ「取り出し位置」を増やします。
        pos += len;

        return len;
    }

    /**
    *   close()メソッド。
    *   ストリームを閉じるために呼び出されます。
    */
    public void close() throws IOException
    {
        System.out.println( "NormalReader#close()" );
    }
}
// Sample.java
import java.io.Reader;
import java.io.PushbackReader;
import java.io.IOException;

public class Sample
{
    public static void main( String[] args )
    {
        NormalReader normalReader = null;
        PushbackReader pushbackReader = null;
        try
        {
            // 「入力元」のNormalReaderクラスを用意します。
            normalReader = new NormalReader();

            // このクラスを対象とするPushbackReaderクラスを用意します。
            pushbackReader = new PushbackReader( normalReader );

            // つまり、

            // NormalReader
            // ↓
            // PushbackReader

            // という形で、文字入力ストリームクラスが連結したことになります。

            while( true )
            {
                // 1バイト取得します。
                int i = pushbackReader.read();
                if( i == -1 )
                {
                    // -1が返されてきたら終わりです。
                    break;
                }

                // 入力します。
                System.out.println( (char)i );
            }
            // あ
            // い
            // う
            // え
            // お

            // このように、pushbackReaderのread()メソッドを呼ぶと、
            // normalReaderのread()メソッドを呼び出します。
        }
        catch( IOException e )
        {
            // 読み込みに失敗した際に、read()メソッドが
            // IOException例外を投げます。
            e.printStackTrace();
        }
        finally
        {
            // 処理が終わったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( pushbackReader != null )
                {
                    pushbackReader.close();
                    // NormalReader#close()

                    // この結果から分かるとおり、stringReaderのclose()メソッドを
                    // 呼ぶと、「入力元」のnormalReaderのclose()メソッドも呼び
                    // 出されるので、本当は下のclose()メソッドを呼ぶ必要は
                    // ありません。でも必ずしも呼ばれるとは限らない
                    // (Javadocの仕様に書かれていない)ので呼んでおきましょう。
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            // 処理が終わったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( normalReader != null )
                {
                    normalReader.close();
                    // NormalReader#close()
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }
        }
    }
}

/**
*   NormalReaderクラス。
*   Readerクラスのサブクラスです。
*/
class NormalReader extends Reader
{
    // 対象の文字列。
    private String source = "あいうえお";
    // 現在の出力位置。
    private int pos = 0;

    /**
    *   read()メソッド。
    *   このクラスを利用する文字入力ストリームクラスの
    *   read()メソッドから呼び出されます。
    *   これをオーバーライドしておけば、他のオーバーロードされた
    *   read()メソッドが呼ばれても、最終的にこのメソッドが呼ばれるので
    *   適切に処理できます。
    */
    public int read( char[] cbuf, int off, int len) throws IOException
    {
        // 対象の文字数を超えていたら(つまり、文字入力ストリーム
        // の末端に達していたら)-1を返します。
        if( pos >= source.length() )
        {
            return -1;
        }

        // 第2引数から第3引数で指定された範囲まで、
        // 第1引数の配列にコピーして返します。
        // (注:実際には引数の整合性チェックや、最大文字数チェック等が
        // 必要です。でないとgetChars()メソッドがIndexOutOfBoundsException例外
        // を投げる可能性があります)
        source.getChars( pos, pos + len, cbuf, off );

        // 取り出した分だけ「取り出し位置」を増やします。
        pos += len;

        return len;
    }

    /**
    *   close()メソッド。
    *   ストリームを閉じるために呼び出されます。
    */
    public void close() throws IOException
    {
        System.out.println( "NormalReader#close()" );
    }
}

この単語を含むページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/11/18
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。