JavaA2Z

KAB-studio > プログラミング > JavaA2Z > バイト入力ストリームとは

バイト入力ストリーム

日本語 バイト入力流れ
英語 byte-input stream
ふりがな ばいとにゅうりょくすとりーむ
フリガナ バイトニュウリョクストリーム

解説

ストリームの一種。
バイトストリームの一種で、入力をう。
文字ストリームと異なり、byteデータを取得するために使用する。
また、バイト出力ストリームと異なり、出力ではなく入力をうために使用する。
 
具体的には、InputStreamクラス及びそのサブクラスを指す。
J2SEの以下のクラスが該当する。
 
InputStream
ByteArrayInputStream
FileInputStream
SequenceInputStream
PipedInputStream
FilterInputStream
BufferedInputStream
PushbackInputStream
ObjectInputStream
DataInputStream
StringBufferInputStream
LineNumberInputStream

 
役割で分けると以下のようになる。
 
スーパークラス
InputStream
 
■入力元
ByteArrayInputStream
FileInputStream
PipedInputStream
 
■中継ぎ
FilterInputStream
BufferedInputStream
PushbackInputStream
SequenceInputStream
 
■取得用
ObjectInputStream
DataInputStream 
 
■使用禁止
StringBufferInputStream
LineNumberInputStream
 
バイト」をストリームから取得するためのクラス
まず、対象とするストリームを元に、「入力元」クラスを決定する。
byte配列を対象とするならByteArrayInputStreamクラスを使用する。
ファイルを対象とするならFileInputStreamクラスを使用する。
PipedOutputStreamクラスを対象とするならPipedInputStreamクラスを使用する。
これらのクラスコンストラクタで「本当の入力元」を指定することで接続する。
 
入力元クラスがあれば、基本的にはストリームからバイトの並びを取得することができる。
read()メソッド文字及び文字列を取得する。
引数を持たないread()メソッドは、1バイトずつ取得する。戻り値intだが、返される値の範囲はbyte、つまり0x00000000~0x000000FFである。また、read()メソッド呼び出し時に「それ以上取得できない場合」、つまりストリームの末端にある場合には-1が返される。
引数(byte[])のread()メソッドは、第1引数配列バイトの並びをコピーする。戻り値にはコピーしたバイト数を返す。「それ以上取得できない場合」には-1を返す。
 
「入力元」クラスだけでは不便な場合は、「中継ぎ」となるクラスを使用する。
バッファリング」、つまりストリームから文字列をまとめて取得する場合にはBufferedInputStreamクラスを使用する。
取得時に他の文字列を挟み込めるようにする場合にはPushbackInputStreamクラスを使用する。
複数のバイト入力ストリームを連結して使用する場合にはSequenceInputStreamクラスを使用する。
これら、「中継ぎ」クラスコンストラクタInputStreamクラスサブクラスを渡すことができるため、コンストラクタに入力元クラスや他の中継ぎクラスを渡すことで、「入力元←中継ぎ←中継ぎ」のようにチェーン化することができる。
チェーン化すると、入力元の方向へとバケツリレーのようにread()メソッド呼び出し、結果を呼び出し元へと返す。その呼び出しの間に、中継ぎクラスバッファリング等の処理をう。
 
さらに、データ取得を容易にする場合には「取得用」のクラスを使用する。
取得用クラスは、バイト配列内に格納されたデータを取得する場合に「便利なメソッド」を提供する。read()メソッドは、1文字ずつ、もしくはbyte配列としてしか返さないため、read()メソッドによる取得は面倒である。
そのため、取得に便利なメソッドを持つ取得用クラスを入力元クラスや中継ぎクラスに接続し、取得用クラスメソッドを呼ぶようにする。
直列化可能なクラスを直接直列化する場合にはObjectInputStreamクラスを使用する。ただし、ストリームには直列化可能クラスObjectOutputStreamクラスで出力されている必要がある。
ストリームからプリミティブ型のデータを取得する場合にはDataInputStreamクラスを使用する。ただし、ストリームにはプリミティブ型のデータがDataOutputStreamクラスで出力されている必要がある。
つまり、どちらも「対になる出力側クラスで出力したもの」を取得できる、ということである。直列化したインスタンスバイト形式にする方法や、プリミティブ型バイト形式に変換する方法は特別なものであり、その「特別な形式」で出力されたものを「特別な形式」で取得できる、ということになる。
 
終了時には、close()メソッド呼び出す
入力元のストリームファイルソケットである場合、処理後は必ずclose()メソッドを呼び終了処理をう必要がある。そのため、close()メソッドfinallyブロック内でうようにする。
念のため、文字列を扱う入力元クラスや、中継ぎクラス、取得用クラスclose()メソッド呼び出す。これは多くの場合必要はないが、呼んでおいた方が精神的にいいだろう。
中継ぎクラス、取得用クラスclose()メソッド呼び出すと、ほとんどのクラスコンストラクタで渡された入力元クラスや中継ぎクラス、つまり「チェーンで連結している先」のclose()メソッド呼び出すため、本当はチェーンの「実際に使用する側」、つまり取得用クラスか、取得用クラスがなければ中継ぎクラスclose()メソッドを呼び出せば、接続先の文字入力ストリームクラスclose()メソッド呼び出してくれるが、仕様上必ずしもそうとは決められていないため、ひとつずつclose()メソッド呼び出した方がいいだろう。
 
ストリームからの取得に失敗したとき等には、IOException例外投げられる
特にファイルソケットが対象の場合、ケーブルが外された、等の外的要因によって取得に失敗する場合があるため、必ず例外の発生に対応する必要がある。
そのため、使用時にはtryブロックで囲み、IOExceptionクラス拾うようにし、その後finallyブロックclose()メソッド呼び出すようにする。
ちなみに、このclose()メソッドIOException例外投げるため、これも拾うようにする。閉じる時の例外のため、う処理は拾った際にはログの出力等をうくらいでいいだろう。
 
このように、入力元クラス、中継ぎクラス、取得用クラスは「チェーン」で接続される。
「入力元クラス←中継ぎクラス←取得用クラス」とチェーン化する場合、まず入力元クラスインスタンスを作成し、その参照を中継ぎクラスインスタンス作成時のコンストラクタに渡し、その参照を取得用クラスインスタンス作成時のコンストラクタに渡す。
このように「接続先の文字入力ストリームクラス」をコンストラクタで渡すことで、read()メソッド呼び出すと、接続先のread()メソッドが呼ばれる仕組みとなる。
 
一般的な使用方法としては、以下のようになる。
バイナリーファイルを開く場合には、入力元クラスFileInputStreamクラス、中継ぎ兼取得用クラスBufferedInputStreamクラスを、取得用クラスDataInputStreamクラスを使用する。
ファイルからの入力はFileInputStreamクラスい、バッファリングをBufferedInputStreamクラスい、バイナリーデータからプリミティブ型への変換をDataInputStreamクラスう。
ただし、この方法が有効なのは、ファイルDataOutputStreamクラスで出力されている場合に限定される。
クラス丸ごと取得する場合には、最後の取得用クラスにはObjectInputStreamクラスを使用する。
ただし、この方法が有効なのは、ファイルObjectOutputStreamクラスによって出力されており、その際に出力されたクラス直列化可能である場合である。
 
それ以外の目的の場合、対象に合わせた入力元ストリームクラスBufferedInputStreamクラスを接続し、byte配列として取得したのち、各バイトを適切な方法で変換することになる。
実際、バイナリーデータは様々な形式のデータであり、その変換には格納されているデータ毎に異なる処理が必要となる。そのため、ストリームからbyte配列に格納してから処理するのがいいだろう。
 
バイト入力ストリームは、バイトデータを取得するためのクラスである。
そのため、文字列テキストファイルといった「明らかに文字列が格納されているストリーム」から取得することには向いていない。これら文字列の取得には文字入力ストリームを使用する。
StringBufferInputStreamクラス及びLineNumberInputStreamクラスは、文字列を取得できそうに見えるが、これらのクラスバイトの処理を適切にわないため「推奨しません」になっており、使用しない方がいい。

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

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

// Sample.java
import java.io.IOException;
import java.io.EOFException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;

public class Sample
{
    public static void main( String[] args )
    {
        // 入出力ファイルの絶対パス。
        // ファイルは存在しなくても構いません。
        // というか存在すると上書きされます。
        String filePath = "D:/test.data";

        // 出力します。

        // FileOutputStreamクラス等の参照型変数。
        // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        DataOutputStream dataOutputStream = null;
        try
        {
            // FileOutputStreamクラスを作ります。
            fileOutputStream = new FileOutputStream( filePath );

            // そのクラスを対象とするBufferedOutputStreamクラスを作ります。
            bufferedOutputStream = new BufferedOutputStream( fileOutputStream );

            // そのクラスを対象とするBufferedOutputStreamクラスを作ります。
            dataOutputStream = new DataOutputStream( bufferedOutputStream );

            // ストリームを通して、データを書き込みます。
            dataOutputStream.writeInt( 100 );
            dataOutputStream.writeUTF( "あいうえお" );
            dataOutputStream.writeBoolean( true );
        }
        catch( IOException e )
        {
            // ファイルが無かった場合等に、この
            // IOException例外が投げられます。
            e.printStackTrace();
            return;
        }
        finally
        {
            // ストリームを扱ったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( dataOutputStream != null )
                {
                    dataOutputStream.close();
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            try
            {
                if( bufferedOutputStream != null )
                {
                    bufferedOutputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( fileOutputStream != null )
                {
                    fileOutputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }

        // 入力します。

        // FileInputStreamクラス等の参照型変数。
        // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        DataInputStream dataInputStream = null;
        try
        {
            // FileInputStreamクラスを作ります。
            fileInputStream = new FileInputStream( filePath );

            // そのクラスを対象とするBufferedInputStreamクラスを作ります。
            bufferedInputStream = new BufferedInputStream( fileInputStream );

            // そのクラスを対象とするDataInputStreamクラスを作ります。
            dataInputStream = new DataInputStream( bufferedInputStream );

            try
            {
                // データを読み込みます。
                int i = dataInputStream.readInt();
                String string = dataInputStream.readUTF();
                boolean b = dataInputStream.readBoolean();
                System.out.println( i );
                System.out.println( string );
                System.out.println( b );
                // 100
                // あいうえお
                // true

                // このように、test.dataファイルにバイナリーデータとして
                // 書き込み、それを取得することができます。
                // 逆に言えば、異なる形式で書き込まれたデータは取得できない
                // ということです。DataOutputStreamクラスとDataInputStreamクラス
                // は対であり、全然関係ないデータの取得にDataInputStreamクラスを
                // 使用することはありません。
            }
            catch( EOFException e )
            {
                System.out.println( "ストリームの終端まで来ました。" );
                // このように、ストリームの最後に来ると
                // EOFExceptionが投げられます。
                // 他のストリームの場合、戻り値に「ストリームの終端まで来た」
                // ことを示す「-1」が返されるのですが、DataInputStreamクラスの
                // 場合、プリミティブ型を返すのでそれができません。
                // そのため、代わりにEOFException例外を投げるのです。
            }
        }
        catch( IOException e )
        {
            // ファイルが無かった場合等に、この
            // IOException例外が投げられます。
            e.printStackTrace();
            return;
        }
        finally
        {
            // ストリームを扱ったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( dataInputStream != null )
                {
                    dataInputStream.close();
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            try
            {
                if( bufferedInputStream != null )
                {
                    bufferedInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( fileInputStream != null )
                {
                    fileInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
}
// Sample.java
import java.io.IOException;
import java.io.EOFException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;

public class Sample
{
    public static void main( String[] args )
    {
        // 入出力ファイルの絶対パス。
        // ファイルは存在しなくても構いません。
        // というか存在すると上書きされます。
        String filePath = "D:/test.data";

        // 出力します。

        // FileOutputStreamクラス等の参照型変数。
        // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        DataOutputStream dataOutputStream = null;
        try
        {
            // FileOutputStreamクラスを作ります。
            fileOutputStream = new FileOutputStream( filePath );

            // そのクラスを対象とするBufferedOutputStreamクラスを作ります。
            bufferedOutputStream = new BufferedOutputStream( fileOutputStream );

            // そのクラスを対象とするBufferedOutputStreamクラスを作ります。
            dataOutputStream = new DataOutputStream( bufferedOutputStream );

            // ストリームを通して、データを書き込みます。
            dataOutputStream.writeInt( 100 );
            dataOutputStream.writeUTF( "あいうえお" );
            dataOutputStream.writeBoolean( true );
        }
        catch( IOException e )
        {
            // ファイルが無かった場合等に、この
            // IOException例外が投げられます。
            e.printStackTrace();
            return;
        }
        finally
        {
            // ストリームを扱ったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( dataOutputStream != null )
                {
                    dataOutputStream.close();
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            try
            {
                if( bufferedOutputStream != null )
                {
                    bufferedOutputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( fileOutputStream != null )
                {
                    fileOutputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }

        // 入力します。

        // FileInputStreamクラス等の参照型変数。
        // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        DataInputStream dataInputStream = null;
        try
        {
            // FileInputStreamクラスを作ります。
            fileInputStream = new FileInputStream( filePath );

            // そのクラスを対象とするBufferedInputStreamクラスを作ります。
            bufferedInputStream = new BufferedInputStream( fileInputStream );

            // そのクラスを対象とするDataInputStreamクラスを作ります。
            dataInputStream = new DataInputStream( bufferedInputStream );

            try
            {
                // データを読み込みます。
                int i = dataInputStream.readInt();
                String string = dataInputStream.readUTF();
                boolean b = dataInputStream.readBoolean();
                System.out.println( i );
                System.out.println( string );
                System.out.println( b );
                // 100
                // あいうえお
                // true

                // このように、test.dataファイルにバイナリーデータとして
                // 書き込み、それを取得することができます。
                // 逆に言えば、異なる形式で書き込まれたデータは取得できない
                // ということです。DataOutputStreamクラスとDataInputStreamクラス
                // は対であり、全然関係ないデータの取得にDataInputStreamクラスを
                // 使用することはありません。
            }
            catch( EOFException e )
            {
                System.out.println( "ストリームの終端まで来ました。" );
                // このように、ストリームの最後に来ると
                // EOFExceptionが投げられます。
                // 他のストリームの場合、戻り値に「ストリームの終端まで来た」
                // ことを示す「-1」が返されるのですが、DataInputStreamクラスの
                // 場合、プリミティブ型を返すのでそれができません。
                // そのため、代わりにEOFException例外を投げるのです。
            }
        }
        catch( IOException e )
        {
            // ファイルが無かった場合等に、この
            // IOException例外が投げられます。
            e.printStackTrace();
            return;
        }
        finally
        {
            // ストリームを扱ったら、最後にclose()メソッドを呼んで
            // 後処理をします。また、これは必ず行うため、
            // finally内で行います。
            try
            {
                if( dataInputStream != null )
                {
                    dataInputStream.close();
                }
            }
            catch( IOException e )
            {
                // close()メソッドはIOExceptionがthrows指定されているので
                // 一応受け取ります。
                e.printStackTrace();
            }

            try
            {
                if( bufferedInputStream != null )
                {
                    bufferedInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( fileInputStream != null )
                {
                    fileInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
}

この単語を含むページ

「みだし」に含まれているページ

「サンプルプログラムとか」に含まれているページ

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