Previous | Next | Trail Map | Writing Java Programs | 入出力ストリーム


ストリームを使用したファイルの連結

SequenceInputStream(in the API reference documentation)は、複数の入力ソースからひとつの入力ストリームを作成する。 次のプログラム例 Concatenate では、SequenceInputStream を使用して、コマンドラインに表示される順序で連続的にファイルを連結する連結ユーティリティを実装する。

次は連結ユーティリティの制御クラスである。

import java.io.*;

class Concatenate {
    public static void main(String[] args) {
        ListOfFiles mylist = new ListOfFiles(args);

        try {
            SequenceInputStream s = new SequenceInputStream(mylist);
            int c;

            while ((c = s.read()) != -1) {
               System.out.write(c);
            }

            s.close();
        } catch (IOException e) {
            System.err.println("Concatenate: " + e);
        }
    }
}

連結ユーティリティが最初に行うことは、ユーザが入力するコマンドライン引数で初期化されるmylist という ListOfFiles オブジェクトを作成することである。 コマンドライン引数は、一緒に連結されるファイルのリストである。mylist は SequenceInputStream の初期化に使用される。つまり、SequenceInputStreamはmylistを使用して、ユーザがリストしたすべてのファイルに対応した新しいInputStreamオブジェクトを得る。

import java.util.
*;
import java.io.*;

class ListOfFiles implements Enumeration {

    String[] listOfFiles;
    int current = 0;

    ListOfFiles(String[] listOfFiles) {
        this.listOfFiles = listOfFiles;
    }

    public boolean hasMoreElements() {
        if (current < listOfFiles.length)
            return true;
        else
            return false;
    }

    public Object nextElement() {
        InputStream is = null;

        if (!hasMoreElements())
            throw new NoSuchElementException("No more files.");
        else {
            try {
                String nextElement = listOfFiles[current];
                current++;
                is = new FileInputStream(nextElement);
            } catch (FileNotFoundException e) {
                System.out.println("ListOfFiles: " + e);
            }
        }
        return is;
    }
}

ListOfFiles は Enumeration(in the API reference documentation)インタフェースを実装する。 プログラムを読み進むと,これがどう働くのかわかってくる。

main() メソッドが SequenceInputStream を作成した後、一度にそこから1バイトを読む。 SequenceInputStream が新規のソースから InputStream を必要とする時(最初のバイトを読む場合や読み込みが現在の入力ストリームの最後に達した時など)、次の InputStream を得るためにEnumerationオブジェクト上のnextElement() を呼び出す。 ListOfFiles は怠惰に FileInputStream オブジェクトを作成する。これは、 SequenceInputStream が nextElement() を呼び出す時はいつでも、 ListOfFiles がリストの次のファイル名に FileInputStream を開き、ストリームを返すことを意味する。 ListOfFiles が読むべきファイルがなくなると(もう要素がない)、nextElement() は null を返し、SequenceInputStream の read()メソッドの呼び出しは、入力の終了を示すために返り値 -1 を返す。

Concatenateは、 SequenceInputStream から読み込んだデータをすべて標準出力に単にエコーしている。

これを試みる: Concatenateをfarrago.txtwords.txt を引数として実行しなさい。この2つのテキストファイルは、このレッスンの別のプログラム例の入力として使用されたものです。

参照

java.io.SequenceInputStream


Previous | Next | Trail Map | Writing Java Programs | 入出力ストリーム