JavaA2Z

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

バイト出力ストリーム

日本語 バイト入力流れ
英語 byte-output stream
ふりがな ばいとしゅつりょくすとりーむ
フリガナ バイトシュツリョクストリーム

解説

ストリームの一種。
バイトストリームの一種で、出力をう。
バイトストリームと異なり、byteデータを取得するために使用する。
また、バイト入力ストリームと異なり、入力ではなく出力をうために使用する。
 
具体的には、OutputStreamクラス及びそのサブクラスを指す。
J2SEの以下のクラスが該当する。
 
OutputStream
ByteArrayOutputStream
FileOutputStream
PipedOutputStream
FilterOutputStream
BufferedOutputStream
ObjectOutputStream
DataOutputStream
PrintStream
 
役割で分けると以下のようになる。
 
スーパークラス
OutputStream
 
■出力先
ByteArrayOutputStream
FileOutputStream
PipedOutputStream
 
■中継ぎ
FilterOutputStream
BufferedOutputStream
 
■出力用
ObjectOutputStream
DataOutputStream
PrintStream
 
バイト」をストリームに出力するためのクラス
まず、対象とするストリームを元に、「出力先」クラスを決定する。
byte配列を対象とするならByteArrayOutputStreamクラスを使用する。
ファイルを対象とするならFileOutputStreamクラスを使用する。
PipedInputStreamクラスを対象とするならPipedOutputStreamクラスを使用する。
これらのクラスコンストラクタで「本当の出力先」を指定することで接続する。
 
出力先クラスがあれば、基本的にはストリームbyteデータを出力することができる。
write()メソッドbyteデータを出力する。
引数(int)のwrite()メソッドは、1バイトずつ出力する。int引数に受け取るが、実際に処理されるのはbyteのサイズのみのため、渡せる値は0x00~0xFFとなる。
引数(byte[])のwrite()メソッドは、渡したbyte配列をまとめて出力する。
 
「出力先」クラスだけでは不便な場合は、「中継ぎ」となるクラスを使用する。
バッファリング」、つまりストリームバイトデータをまとめて出力する場合にはBufferedOutputStreamクラスを使用する。
この「中継ぎ」クラスコンストラクタOutputStreamクラスサブクラスを渡すことができるため、コンストラクタに出力先クラスや他の中継ぎクラスを渡すことで、「出力先←中継ぎ←中継ぎ」のようにチェーン化することができる。
チェーン化すると、出力先の方向へとバケツリレーのようにwriter()メソッド呼び出し、その際にバイトデータを渡していき出力先ストリームへと出力する。その呼び出しの間に、中継ぎクラスバッファリング等の処理をう。
 
さらに、クラスインスタンスプリミティブ型の出力を容易にする場合には「出力用」のクラスを使用する。
出力用クラスは、クラスインスタンスプリミティブ型を出力する場合に「便利なメソッド」を提供する。write()メソッドbyteしか出力できないため、write()メソッドでは不便である。
そのため、出力に便利なメソッドを持つ出力用クラスを出力先クラスや中継ぎクラスに接続し、出力用クラスメソッドを呼ぶようにする。
直列化可能なクラスを直接直列化する場合にはObjectOutputStreamクラスを使用する。ただし、出力するクラス直列化可能である必要があり、取得にはObjectInputStreamクラスを使用する必要がある。
ストリームプリミティブ型のデータを出力する場合にはDataOutputStreamクラスを使用する。ただし、ストリームから取得するためにはDataInputStreamクラスを使用する必要がある。
つまり、どちらも「対になる出力側クラスで出力したもの」を取得できる、ということである。直列化したインスタンスバイト形式にする方法や、プリミティブ型バイト形式に変換する方法は特別なものであり、その「特別な形式」で出力されたものを「特別な形式」で取得できる、ということになる。
PrintStreamクラスストリーム文字列形式で出力する。print()メソッド及びprintln()メソッドを持ち、これらはあらゆるプリミティブ型オーバーロードされている。プリミティブ型なら全て渡すことができ、文字列へと変換し、さらにbyte配列へと変換してから、出力先クラスのwrite()メソッド呼び出して出力する。println()メソッドは出力時に改行も加える。文字列として出力するため後から取得するためには向かないが、単純に出力する分には向いている。
 
終了時には、close()メソッド呼び出す
出力先のストリームファイルソケットである場合、処理後は必ずclose()メソッドを呼び終了処理をう必要がある。そのため、close()メソッドfinallyブロック内でうようにする。
念のため、文字列を扱う出力先クラスや、中継ぎクラス、出力用クラスclose()メソッド呼び出す。これは多くの場合必要はないが、呼んでおいた方が精神的にいいだろう。
中継ぎクラス、出力用クラスclose()メソッド呼び出すと、ほとんどのクラスコンストラクタで渡された出力先クラスや中継ぎクラス、つまり「チェーンで連結している先」のclose()メソッド呼び出すため、本当はチェーンの「実際に使用する側」、つまり出力用クラスか、出力用クラスがなければ中継ぎクラスclose()メソッドを呼び出せば、接続先の文字出力ストリームクラスclose()メソッド呼び出してくれるが、仕様上必ずしもそうとは決められていないため、ひとつずつclose()メソッド呼び出した方がいいだろう。
 
ストリームへの出力に失敗したとき等には、IOException例外投げられる
特にファイルソケットが対象の場合、ケーブルが外された、等の外的要因によって出力に失敗する場合があるため、必ず例外の発生に対応する必要がある。
そのため、使用時にはtryブロックで囲み、IOExceptionクラス拾うようにし、その後finallyブロックclose()メソッド呼び出すようにする。
ちなみに、このclose()メソッドIOException例外投げるため、これも拾うようにする。閉じる時に投げられる例外のため、う処理は拾った際にはログの出力等をうくらいでいいだろう。
 
このように、出力先クラス、中継ぎクラス、出力用クラスは「チェーン」で接続される。
「出力先クラス←中継ぎクラス←出力用クラス」とチェーン化する場合、まず出力先クラスインスタンスを作成し、その参照を中継ぎクラスインスタンス作成時のコンストラクタに渡し、その参照を出力用クラスインスタンス作成時のコンストラクタに渡す。
このように「接続先の文字出力ストリームクラス」をコンストラクタで渡すことで、write()メソッド呼び出すと、接続先のwrite()メソッドが呼ばれる仕組みとなる。
 
一般的な使用方法としては、以下のようになる。
バイナリーファイルを出力する場合には、出力先クラスFileOutputStreamクラス、中継ぎクラスBufferedOutputStreamクラス、出力用クラスDataOutputStreamクラスを使用する。プリミティブ型からbyte配列への変換はDataOutputStreamクラスい、それをBufferedOutputStreamクラスでまとめて出力し、最後はFileOutputStreamクラスファイルへと出力する。
ただし、この方法で出力したファイルバイナリーファイルとなるため、ファイルからデータを取得するためにはDataInputStreamクラスで出力されている場合に限定される。
クラス丸ごと出力する場合には、出力用クラスにはObjectOutputStreamクラスを使用する。
ただし、この方法が有効なのは、出力するクラス直列化可能であり、さらにファイルから取得するためにはObjectInputStreamクラスを使用する必要がある。
 
それ以外の目的の場合、対象に合わせた出力先ストリームクラスBufferedOutputStreamクラスを接続し、byte配列として出力する。
実際、バイナリーデータは様々な形式のデータであり、その変換には格納されているデータ毎に異なる処理が必要となる。そのため、データを適切な形式でbyte配列に変換してから出力するのがいいだろう。
 
バイト出力ストリームは、バイトデータを出力するためのクラスである。
そのため、文字列テキストファイルといった「文字列形式での出力」には向いていない。これら文字列の出力には文字出力ストリームを使用する。
ただし、PrintStreamクラスでも文字列形式で出力できるため、問題がなければPrintStreamクラスを使用してもよい。

(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」表紙の説明をご覧ください。