16. 出力ストリーム

ファイルやネットワーク、標準出力などに結果を出力する場合に使います。

(1) ファイルに書き込むためのストリーム

 ストリームを使ったプログラムの1つ目はファイルへの書き込みです。ファイルに書き込みたい場合には java.io.FileOutputStream というクラスを使います。

 このクラスは出力ストリームの基本機能を提供する java.io.OutputStream クラスのサブクラスです。OutputStream クラスは抽象クラスなので、実際に使われるのはサブクラスになります。

 まずは FileOutputStream クラスのオブジェクトを作ります。簡単なコンストラクタを2種類だけ紹介しておきます。
FileOutputStream(File file) throws FileNotFoundException

FileOutputStream(String fileName) throws IOException

 1つ目のコンストラクタでは書き込みをしたいファイル名を File オブジェクトで引数に指定します(File クラスは中級編13章で紹介しました)。2つ目のコンストラクタを使う場合には、ファイル名をそのまま指定します。

 これらのコンストラクタを使う場合は throws 節に書いてあるように例外が発生する可能性があるので try ブロック(入門編13章)の中に入れておく必要があります。

 このようなコンストラクタを使って FileOutputStream オブジェクトを生成した時点でファイルをオープンしたことになります(FileOutputStream には open( ) というメソッドはありません)。

FileOutputStream fos = new FileOutputStream("filetest");

FileOutputStream オブジェクトを生成すると0バイトのファイルができます。ただし、ファイルを生成できないときやセキュリティの解除をしていないアプレットなどの場合は例外が発生します。


(2) ファイルに書き込む

 FileOutputStream のオブジェクトを使ってデータを書き込んでいきましょう。書き込み用のメソッドは次の3種類があります。

1. void write(byte[ ] b) throws IOException
 バイト配列をこのファイルに書き込みます。

2. void write(byte[ ] b, int start, int len) throws IOException
 バイト配列の start 番目から始まる len バイトをファイルに書き込みます。

3. void write(int b) throws IOException
 バイトデータをファイルに書き込みます。

4. void close( ) throws IOException
 FileOutputStream を閉じます。

 注意することは、どのメソッドを使った時もすべてバイト単位のデータで書き込まれるとういことです。3番目の write( ) は引数が int 型ですが、書き込みはバイト単位になってしまうため、byte 型の範囲をこえる値を書き込むとビットが足りない分に関しては切り捨てられてしまいます。

 また、コンストラクタと同じように write( ) を使うときは例外が発生する可能性があるので、これも try ブロックの中に入れておきます。

 下の例題実行後には filetest というファイルサイズが5バイトのファイルができあがります。

  FileOutTest.java

import java.io.*;

class FileOutTest {
    public static void main(String args[]) {
        FileOutputStream fos = null;
        int data[] = { 10,20,30,40,50 };
        
        try {
            fos = new FileOutputStream("filetest");
        } catch (Exception e) {
            System.out.println("ファイルを開けません");
            e.printStackTrace();
        }
        
        try {
            for (int i=0;i<data.length;i++)
                fos.write( (byte)data[i] );
        } catch (Exception e) {
            System.out.println("書き込みに失敗");
            e.printStackTrace();
        }

        try {
            fos.close(); 
        } catch (Exception e) {
            System.out.println("ストリームを閉じられません");
            e.printStackTrace();
        }
    }
}


 実行方法

C:\java_test>java FileOutTest


(3) フィルタストリーム

 FileOutputStream でファイルにデータを書き込むことができるようになりました。しかし、FileOutputStream ではバイト単位のデータしか書き込めません。計算結果を書き込もうにも8ビット(byte 型のサイズ)を越える値については正しく書き込めません。どうしてもというなら、シフト演算をして書き込むしかありません。

 これでは使いづらいので Java ではフィルタストリームというものが用意されています。出力用フィルタストリームは java.io.FilterOutputStream クラスのサブクラスを使います。フィルタストリームでは既存のストリームに接続して基本的なストリーム機能の拡張やデータの変換を行います。たとえば基本データ型を書き込みたい場合には java.io.DataOutputStream クラスを使います。

 フィルタストリームを使うには、既にストリームが存在していなければいけません。そこでまず、ファイルに書き込むための FileOutputStream を作っておきます。そして、このストリームに接続するフィルタストリームの DataOutputStream オブジェクトを作ります。コンストラクタは以下の通りです。
DataOutputStream(OutputStream out)

 この形式をみてもわかるように、出力フィルタストリームを使うには既存の出力ストリームが必要なわけです。このように DataOutputStream を接続すると、以下の図のような流れになり、基本データ型もそのまま書き込むことができるようになります。


FileOutputStream fos = new FileOutputStream("filetest");
DataOutputStream dos = new DataOutputStream(fos);


 DataOutpuStream を使ってデータを書き込むには以下のメソッドを使います。機能が拡張されているのがわかりますね(基本機能の3つの write( ) も使えます)。すべてのメソッドは IOException を投げる可能性があります。

1. void writeBoolean(boolean v)
 boolean 値を書き込みます。

2. void writeByte(int v)
 byte 値を書き込みます。

3. void writeBytes(String s)
 文字列を一連のbyte型として書き込みます。

4. void writeChar(int v)
 char を上位バイトを先頭とする 2 バイトデータとして書き込みます。

5. void writeChars(String s)
 文字列を一連のchar型データとして書き込みます。

6. void writeDouble(double v)
 double 型 データを書き込みます。

7. void writeFloat(float v)
 float 型データを書き込みます。

8. void writeInt(int v)
 int 型データを書き込みます。

9. void writeLong(long v)
 long 型データを書き込みます。

10. void writeShort(int v)
 short 型データを書き込みます

11. void writeUTF(String str)
 文字列を UTF-8 エンコーディングで書き込みます。

12. void flush( )
 出力ストリームをフラッシュします。

 注意することは、これらの writeXXX( ) で書き込んだデータは、このあと紹介する DataInputStream クラスの readXXX( ) でなければ正しく読み込めないということです。

  DataOutTest.java (例外処理は簡素化しています)

import java.io.*;

class DataOutTest {
    public static void main(String args[]) {
        try {
            FileOutputStream fos = new FileOutputStream("filetest2");
            DataOutputStream dos = new DataOutputStream(fos);
            dos.write(10);
            dos.writeInt(100000);
            dos.writeUTF("Java Java Java");
            dos.close();
            fos.close();
        } catch (Exception e) {
            System.out.println("例外発生");
            e.printStackTrace();
        }
    }
}


 実行方法

C:\java_test>java DataOutTest

DataOutputStream を閉じるときも close( ) を使います。
(DataOutputStream を閉じると、接続している既存のストリームも閉じてしまうようです。)


DataOutputStream の接続先を System.out にすると標準出力に出力されます。

前の章(15.ストリーム)   次の章(17.入力ストリーム)