WisdomSoft - for your serial experiences.

10.1 標準入出力とストリーム

Java による標準入出力とストリームの概念について解説します。システムで標準入出力を切り替えるリダイレクトという機能を用いることによって、プログラムを変更することなく出力先や入力元を変更できます。

10.1.1 ストリーム

これまで、画面に文字を表示する手段として System.out.println() メソッドを呼び出してきました。このメソッドに対する具体的な説明はまだしていませんでした。この場では、これらの Java の入出力システムを解説すると同時に、画面に文字を表示する仕組みを詳しく説明します。

そもそも、System.out.println() という記述は System クラスの out 読み取り専用フィールドの println() メソッドを表しています。System クラスとは、インスタンスを生成することができない、システムに密着した有用なフィールドやメソッドを公開するクラスです。このクラスの out フィールドには、データを出力する対象と関連付けられたオブジェクトが格納されています。

Java の入出力は、ハードウェアや低水準なプログラム仕様を隠蔽し、抽象的な方法でデータをやり取りすることができるストリームと呼ばれる方式を採用しています。C 言語の開発経験者はある程度理解していると思いますが、ストリームとはデータの入力や出力先を抽象化した概念のことです。開発者の立場としては、ファイルやメモリに文字を書き込んだり、プリンタやディスプレイに文字を出力するのも、対象が異なるだけで「文字を送る」という意味では同じです。ストリームは、出力先がディスプレイでも、プリンタでも、テキストファイルでも、ネットワークでも、同一の方法でデータを渡すことができるのです。入力もまた、対象がキーボードでも、ファイルでも、ネットワーク上からダウンロードしたデータでも、同じ方法で受け取ることができます。

デフォルトでは、System.out フィールドは標準出力へのストリームです。標準出力とは、オペレーティング・システムが定めているプログラムのテキストを出力する対象を表します。標準出力を決定するのはプログラムの開発者ではなく、システムの利用者です。これまで、System.out.println() を呼び出すと、画面に文字が表示されると説明しましたが、正確ではありません。実は、システムの利用者が標準出力をテキストファイルに指定すれば、println() メソッドはファイルに文字を書き込むでしょう。対象がプリンタであれば、出力した文字が印刷されます。出力対象はディスプレイ、プリンタ、ファイルなどの可能性がありますが、これらへの出力が println() メソッドだけで共通に行えるのは、ストリームという概念のおかげなのです。

標準出力の設定方法は、利用しているオペレーティング・システムによって異なります。標準出力先を変更して2.1 はじめてのJava言語コード2を実行すれば、ディスプレイ以外にテキストが出力できることを確認することができます。例えば、Windows のコマンドプロンプトを利用している場合、コマンドの後に > 記号とファイル名を指定することによって、そのファイルが標準出力となります。println() メソッドで出力した文字列は、ディスプレイではなくファイルに書き込まれるでしょう。

実行結果
>java Test > out.txt

>type out.txt
Kitty on your lap

上記のように標準出力のストリームを変更することで、プログラムには変更を加えることなく、プログラムの結果を任意の場所に出力できます。出力対象の決定方法さえわかれば、これまで何度も使ってきた println() メソッドで文字列をどこにでも転送することができるのです。ストリームの柔軟性を理解していただけたことでしょう。

10.1.2 Systemクラス

System クラスでは、標準入出力のストリームを公開するフィールドや、設定を行うメソッドを公開しています。

表1 System クラス(抜粋)
フィールド 解説
static PrintStream err 「標準」エラー出力ストリームです。
static InputStream in 「標準」入力ストリームです。
static PrintStream out 「標準」出力ストリームです。
メソッド
static void exit(int status) 現在実行している Java 仮想マシンを終了します。
static void gc() ガベージコレクタを実行します。
static void loadLibrary(String libname) 引数 libname によって指定されるシステムライブラリをロードします。
static void setErr(PrintStream err) 「標準」エラー出力ストリームを割り当てし直します。
static void setIn(InputStream in) 「標準」入力ストリームを割り当てし直します。
static void setOut(PrintStream out) 「標準」出力ストリームを割り当てし直します。

表1は、System クラスの中でも特に今回の説明に重要なメンバを抜粋したものです。このほかにもいくつかのメソッドが公開されていますが割愛します。

System.out フィールドは何度も使ってきました。println() メソッドを呼び出していたのは、このフィールドに割り当てられているオブジェクトだったのです。out フィールドは PrintStream 型となっています。PrintStream クラスは、様々な型を文字列表現としてストリームに出力する機能を提供しています。このクラスについては「10.2 ストリームへの書き込み」で詳しく紹介します。

err フィールドは、標準エラー出力のストリームです。標準エラー出力とは、標準出力と異なり、エラーメッセージなどを表示するためのストリームです。通常、例外情報などはこちらに出力するべきだと考えられるでしょう。

コード1
class Test {
	public static void main(String args[]) {
		System.err.println("標準エラー出力です");
		System.out.println("標準出力です");
	}
}
実行結果
>java Test > out.txt
標準エラー出力です

>type out.txt
標準出力です

コード1は、標準エラー出力と、標準出力それぞれに文字列を出力しています。標準出力先をファイルに変更して実行してみると、out フィールドを用いて出力した文字列は表示されず、画面には標準エラーに出力した文字列だけが表示されるでしょう。

もちろん、標準エラー出力がディスプレイに設定されている保障はどこにもありません。これは、実行時のオペレーディング・システムの設定に依存する問題ですが、一般的にはエラーのような重要な情報は、利用者の目に届く装置となるでしょう。