![]() ![]() ![]() ![]() |
入出力ストリーム |
java.io パッケージは、 PipedInputStreams
とPipedOutputStream
の2つのクラスを含んでおり、パイプの入出力コンポーネントを実装する。 パイプは、プログラム(あるいはスレッド)からの出力を別のプログラムの入力に接続するために使用される。
パイプ処理された入出力ストリームは、他者によって入力として用いらる出力を生成するメソッドに便利である。 たとえば、テキストをソートしたり、逆転するなどの種々のテキストユーティリティを実装するクラスを書いていると仮定する。 (注:「逆転する」とは単語中の文字を逆順に並び替えること) もしこれらのメソッドの一つの出力が、別のメソッドの入力として用いられることができたなら、素晴らしいであろう。 したがって、いくつかの機能を実行するために一連のこれらのメソッドをつなげることができる。 ここで示すパイプは、単語のリストを逆転、ソートし、さらに逆転し、韻を踏んでいる単語リストを作成する。
![]()
パイプ処理されたストリームがなくては、それぞれの手順の間に一時ファイルを作成しなければならない。
![]()
上記のパイプ処理されたストリームを使用した逆転とソートのメソッドを実装するプログラムを調査して、韻を踏む単語のリストを作成するために上記に示したパイプで逆転とソートのメソッドを使用する。
最初に、 RhymingWords クラスには、main() 、 reverse() 、 sort() の3つのメソッドが含まれる。 main()メソッドはメインプログラムのコードを提供する。そしてそれは入力ファイルを開き、入力ファイル上の単語を逆転、ソート、逆転する他の2つのメソッドを使用し、そして標準出力に結果を書き込む。
reverse() と sort() はパイプで使用されるように設計されている。reverse() と sort の双方は、InputStream からデータを読み込み、それを処理(文字列を逆転あるいはソートする)して、別のメソッドが読みやすい PipedInputStreams を作リ出す。 詳細に reverse() を見てみる。 sort()メソッドは reverse() によく似ていて、それ自身の検討を必要としない。
public static InputStream reverse(InputStream source) { PipedOutputStream pos = null; PipedInputStream pis = null; try { DataInputStream dis = new DataInputStream(source); String input; pos = new PipedOutputStream(); pis = new PipedInputStream(pos); PrintStream ps = new PrintStream(pos); new WriteReversedThread(ps, dis).start(); } catch (Exception e) { System.out.println("RhymingWords reverse: " + e); } return pis; }reverse() メソッドは、逆転される文字列のリストを含む source と呼ばれる InputStream を引数として取る。reverse() は source と呼ばれる InputStream に DataInputStream をマップする。そうすると revevse()はDataInputStream のreadline()メソッドを使用してこのファイルからそれぞれの行を読むことができる。フィルタストリームで InterStream に接続(マップ)される。そして、 InputStream のデータは読み込み時にフィルタ処理される。フィルタストリームとの作業 ではこれについて説明する。)
次のにreverse() は PipedOutputStream を作成し、 PipedInputStreams をそれに接続する。 PipedOutputStream をPipedInputStreams に接続しなければならないことを覚えておくこと。reverse() は、PrintStreamをPipedOutputStream に マップする。そしてreverse()はPrintStreamのprintln()メソッドを使用して,PipedOutputStream に文字列を書くことができる。
これで reverse() はWriteReversedThreadスレッドオブジェクトを作成し、このスレッドオブジェクトに PipedOutputStream に接続した PrintStream と source に接続した DataInputStream の2つのストリームを渡してこのスレッドオブジェクトを開始する。 WriteReversedThread オブジェクトは DataInputStream から単語を読み取って、それらを逆転し、PrintStream に出力を書き込む(これによって、出力をパイプに書き込む)。 スレッドオブジェクトにより、パイプの両方の端が他とは独立して実行することができ、パイプの片方の端が入出力呼び出しが完了するのを待ってブロックする時、main() メソッドがロックするのを防ぐことができる。
次は、WriteReversedThread の run メソッド である。
public void run() { if (ps != null && dis != null) { try { String input; while ((input = dis.readLine()) != null) { ps.println(reverseIt(input)); ps.flush(); } ps.close(); } catch (IOException e) { System.out.println("WriteReversedThread run: " + e); } } }PipedOutputStream が PipedInputStreams に接続されているので、 PipedOutputStream に書かれたすべてのデータは PipedInputStreams に流れる。 データは別プログラムあるいはスレッドによって PipedInputStreams から読み取られる。 reverse() は,呼出しプログラムが使用する PipedInputStreams を返す。
sort() メソッドは reverse()メソッドと同じパターンに従う。
- パイプ処理された出力ストリームを開く。
- パイプ処理された入力ストリームをパイプ処理された出力ストリームに接続する。
- SortThread オブジェクトを使用して、パイプ処理された入力ストリームから読み込んでパイプ処理された出力ストリームに書き込む。そしてこの出力ストリームが他者が使用するパイプ処理された入力ストリームになる。
- 一杯になったパイプ処理された入力ストリームは誰か他の人に渡され読み込みが行われる。
reverse() と sort() への呼び出しは、1つのメソッドからの出力が次のメソッドの入力になるように、一緒にカスケードにされることができる。 実際は、 main() メソッドがまさにこれを行う。 韻を踏んでいる単語のリストを作成するためにreverse() 、 sort() 、 reverse() への呼び出しをカスケードする。
InputStream rhymedWords = reverse(sort(reverse(words)));RhymingWords を このファイルの単語 で実行すると、次のような出力になる。
Java interface image language communicate integrate native string network stream program application animation exception primer container user graphics threads tools class bolts nuts object applet environment development argument component input output anatomy security注意深く見てみると、environment、development、 argument、component のような「韻を踏む」単語は一緒に分類される。
参照
![]() ![]() ![]() ![]() |
入出力ストリーム |