標準ストリーム

標準ストリームとは、UNIXやUnix系オペレーティングシステム  において、プログラムの活動実体であるプロセスとその実行環境の間の接続として、あらかじめ確立されている入出力チャネルである。OSのカーネルではなくシェルで実装されている機能だが、広く使われているため標準化されている。UNIXやUnix系OSでは3つの入出力ストリームが定義される。

一部のプログラミング言語の実装では、UNIXやUnix系以外のシステムでもUnixと同様の使い勝手を提供するよう、これらを模倣するものがある。MS-DOSにはさらに、シリアルポートに対応する標準補助入出力 、プリンターに対応する標準プリンター出力  もあり、今でもWindowsでAUXやPRNという名前をファイルやコマンド等に使おうとすると問題を起こしたりするのは、これらに関してMS-DOSとの互換性があるためである。

1. 背景
-----

UNIX以前の多くのOSでは、プログラムは明示的に適当な入出力に接続する必要があった。多くのシステムにはOS固有の複雑な事情があり、環境設定をしたり、ローカルなファイルテーブルにアクセスしたり、必要なデータセットを指定したり、カードリーダー、磁気テープドライブ、ディスクドライブ、ラインプリンタ、カードパンチ、対話型端末などを正しく扱うといったプログラミング以前のハードルが多数存在した。

UNIXはこの状況に対していくつかの重要な進化を遂げている。その1つが「抽象デバイス」である。これはプログラム自体がやり取りするデバイスに関する知識を持たなくて済むようにしたものである。古いOSではプログラマはレコード構造を知っておく必要があり、直交性のないことが多いデータ意味論やデバイス制御を扱う必要があった。UNIXはデータストリームという概念によってこのような複雑さを排除した。データストリームとは逐次的なデータバイト列であり、End Of Fileまでリード可能である。プログラムはまた好きなだけバイト列を出力でき、事前にバイト数を宣言しておく必要もないし、それらがどのようにグループ化されているかを宣言する必要もない。

もう1つのUNIXの成し遂げたブレークスルーは、自動的に入力と出力を関連付けることであり、典型的な入力-処理-出力型プログラムでは入出力の設定を何もする必要がない。対照的にそれ以前のOSでは複雑なジョブ制御言語を使ってコネクションを確立するか、それとほぼ同等のことをプログラム本体で行う必要があった。

UNIXが標準ストリームを提供したことで、そのC言語実行環境もそれをサポートするようになった。結果として、多くのC言語実行環境はOSが何であっても同等な機能を提供するようになっている。

2. 標準入力 
---------------

標準入力はプログラムに入ってくるデータである。プログラムは //read// 操作を使ってデータ転送を要求する。全てのプログラムが入力を要求するわけではない。例えば//dir//や//ls//プログラムは、標準入力からのデータを使わないで処理を行う。

リダイレクトしない限り、標準入力はプログラムを起動した端末のキーボードになっている。

標準入力のファイル記述子は0である。POSIXの では STDIN_FILENO と定義されている。対応する での変数は FILE* stdin、 での変数は std::cin である。

3. 標準出力 
----------------

標準出力はプログラムが書き出すデータのストリームである。プログラムは //write// 操作を使ってデータ転送を要求する。全てのプログラムが出力を要求するわけではない。例えばファイル改名コマンドは何も出力しない。

このストリームのデフォルト宛先はプログラムを起動した端末のディスプレイになっている。リダイレクトにより容易に宛先を変更できる。

標準出力のファイル記述子は1である。POSIXのではSTDOUT_FILENOと定義されている。対応するでの変数はFILE* stdout、での変数はstd::coutである。

4. 標準エラー出力 
-------------------

標準エラー出力は、エラーメッセージや診断メッセージを出力するためのもう1つの出力ストリームである。標準出力とは独立しているため、一方だけをリダイレクトすることができる。デフォルトでは端末になっており、標準出力がリダイレクトされていて画面に表示されなくとも、エラーメッセージだけはユーザーが目にするようになっている。例えば、パイプで出力が他のプログラムの入力に接続されている場合でも、標準エラー出力は直接端末のディスプレイに届く。

標準出力と標準エラー出力を同じ出力先にリダイレクトすることもよくある。バッファが関与しない場合、メッセージはプログラムが書いた順序で現れる。典型的な例として、標準エラー出力がバッファリングされておらず、標準出力が行単位でバッファリングされている場合、後から標準エラー出力に書かれたメッセージが先に端末上に表示されることがある。

標準エラー出力のファイル記述子は2である。POSIXのではSTDERR_FILENOと定義されている。対応するでの変数はFILE* stderr、での変数は2つありstd::cerrとstd::clogである。前者はバッファリングされておらず、後者はC++の他のストリームと同様にバッファリングされている。

5. 歴史
-----

5.1. 1950年代: FORTRAN
--------------------

FORTRANにもUNIXのようなファイル記述子があり、UNIT=5がstdin、UNIT=6がstdoutを表す。 ! FORTRAN 77 example PROGRAM MAIN READNUMBER WRITE')' NUMBER IS: ',NUMBER END

5.2. 1960年: ALGOL 60
--------------------

ALGOL 60には、標準ストリームの概念が存在しない。

5.3. 1968年: ALGOL 68
--------------------

ALGOL 68では、入力  と出力  をあわせてtransputと呼ぶ。Cornelis H. A. Kosterは//transput//標準を定義した。この標準にはstand in、stand out、stand error、stand backがある。

例:



5.4. 1970年代: CとUnix
-------------------

C言語では、stdin、stdout、stderrのストリームはUnixのファイル記述子 0、1、2にそれぞれ対応する。

5.5. 1995年: Java
----------------

Javaでは、標準ストリームはjava/lang 、java/lang 、java/lang  で参照される。 public static void main { try { BufferedReader br = new BufferedReader); String s = br.readLine; double number = Double.parseDouble; System.out.println; } catch  { System.err.println); } }

5.6. 2000年代: .NET
-----------------

C#などの.NET言語では、標準ストリームはSystem.Console.In 、System.Console.Out 、System.Console.Error  で参照される。stdinおよびstdoutストリームの基本的な読み書きの場合、クラスSystem.Consoleを使って直接アクセスすることもできる。

System.Console.In、System.Console.Out、System.Console.Errorは System.IO.TextReader  および System.IO.TextWriter  オブジェクトであり、テキストベースの標準ストリームにしかアクセスできない。標準ストリームへの完全バイナリアクセスにはSystem.IO.Streamオブジェクトを使う必要があり、それぞれSystem.Console.OpenStandardInput、System.Console.OpenStandardOutput、System.Console.OpenStandardErrorで得られる。 // C# example public static int Main { try { string s = System.Console.In.ReadLine; double number = double.Parse; System.Console.Out.WriteLine; return 0;

// If Parse threw an exception } catch  { System.Console.Error.WriteLine; } catch  { System.Console.Error.WriteLine; } catch  { System.Console.Error.WriteLine; }

return -1; }<WtXmlEndTag />

' Visual Basic .NET example

Public Function Main As Integer Dim number As Double Dim s As String

Try s = System.Console.In.ReadLine number = CDbl System.Console.Out.WriteLine Return 0 Catch e As System.InvalidCastException ' if CDbl threw an exception System.Console.Error.WriteLine Return 1 End Try End Function<WtXmlEndTag />

System.Diagnostics.Processクラスを使うと、そのインスタンスプロパティStandardInput、StandardOutput、StandardErrorを使ってそのプロセスの標準ストリームにアクセスできる。

5.7. GUI
--------

グラフィカルユーザインタフェース  では滅多に標準ストリームを使わない。当然、GUIプログラムをリダイレクトしたり、GUIプログラムでパイプを使うことはない。GUIにとって標準ストリームに近いのはコピー・アンド・ペーストであろう。しかし、ユーザーの操作を必要とするため、多数の「ペースト」を行うのは効率的ではない。特筆すべき例外としてdwmというタイル型ウィンドウマネージャでは、stdout上のデータをステータスバーに直接表示する。

特にUnix系の一部のGUIプログラムは、デバッグ情報を標準エラー出力に書き込んでいることがある。また、標準入力にファイルを指定する形式で働くものもあり、Unix系のメディアプレーヤーに多い。

GTK-serverでは、GUIを構築するインタプリタ型プログラムとのインタフェースにstdinを使うことができる。

6. 関連項目
-------

リダイレクト 
パイプ 
ストリーム 
入出力
fgetc

7. 参考文献
-------

//KRONOS 2.1 Reference Manual//, Control Data Corporation, Part Number 60407000, 1974
//NOS Version 1 Applications Programmer's Instant//, Control Data Corporation, Part Number 60436000, 1978
[1], Honeywell Corporation, 1981
[2], IBM Corporation, 1981
//Lions' Commentary on UNIX Sixth Edition//, John Lions, ISBN 1-57398-013-7, 1977
[3], Microsoft Corporation, 2008

8. 外部リンク
--------

[4] - by The Linux Information Project