標準ストリーム

標準ストリーム（）とは、UNIXやUnix系オペレーティングシステム (OS) において、プログラムの活動実体であるプロセスとその実行環境（通常は端末）の間の接続として、（プロセスから見ると）あらかじめ確立されている入出力チャネル（パイプ）である。OSのカーネルではなくシェルで実装されている機能だが、広く使われているため標準化されている。UNIXやUnix系OSでは3つの入出力ストリーム（標準入力、標準出力、標準エラー出力）が定義される。
一部のプログラミング言語の実装では、UNIXやUnix系以外のシステムでもUnixと同様の使い勝手を提供するよう、これらを模倣するものがある。MS-DOSにはさらに、シリアルポートに対応する標準補助入出力 (stdaux)、プリンターに対応する標準プリンター出力 (stdprn) もあり、今でもWindowsでcodice_1やcodice_2という名前をファイルやコマンド等に使おうとすると問題を起こしたりするのは、これらに関してMS-DOSとの互換性があるためである。
背景.
UNIX以前の多くのOSでは、プログラムは明示的に適当な入出力に接続する必要があった。多くのシステムにはOS固有の複雑な事情があり、環境設定をしたり、ローカルなファイルテーブルにアクセスしたり、必要なデータセットを指定したり、カードリーダー、磁気テープドライブ、ディスクドライブ、ラインプリンタ、カードパンチ、対話型端末などを正しく扱うといったプログラミング以前のハードルが多数存在した。
UNIXはこの状況に対していくつかの重要な進化を遂げている。その1つが「抽象デバイス（）」である。これはプログラム自体がやり取りするデバイスに関する知識を持たなくて済むようにしたものである。古いOSではプログラマはレコード構造を知っておく必要があり、直交性のないことが多いデータ意味論やデバイス制御を扱う必要があった。UNIXはデータストリームという概念によってこのような複雑さを排除した。データストリームとは逐次的なデータバイト列であり、End Of Fileまでリード可能である。プログラムはまた好きなだけバイト列を出力でき、事前にバイト数を宣言しておく必要もないし、それらがどのようにグループ化されているかを宣言する必要もない。
もう1つのUNIXの成し遂げたブレークスルーは、自動的に入力と出力を関連付けることであり、典型的な入力-処理-出力型プログラムでは入出力の設定を何もする必要がない。対照的にそれ以前のOSでは複雑なジョブ制御言語を使ってコネクションを確立するか、それとほぼ同等のことをプログラム本体で行う必要があった。
UNIXが標準ストリームを提供したことで、そのC言語実行環境もそれをサポートするようになった。結果として、多くのC言語実行環境（および派生言語の実行環境）はOSが何であっても同等な機能を提供するようになっている。
標準入力 (stdin).
標準入力（, stdin）はプログラムに入ってくるデータ（テキストであることが多い）である。プログラムは "read" 操作を使ってデータ転送を要求する。全てのプログラムが入力を要求するわけではない。例えば"dir"や"ls"プログラム（ディレクトリ内のファイル名の一覧を表示する）は、標準入力からのデータを使わないで処理を行う。
リダイレクトしない限り、標準入力はプログラムを起動した端末のキーボードになっている。
標準入力のファイル記述子は0（ゼロ）である。POSIXの codice_3 では codice_4 と定義されている。対応する codice_5 での変数は codice_6、codice_7 での変数は codice_8 である。
標準出力 (stdout).
標準出力（, stdout）はプログラムが書き出すデータのストリームである。プログラムは "write" 操作を使ってデータ転送を要求する。全てのプログラムが出力を要求するわけではない。例えばファイル改名コマンド（"mv"、"move"、"ren" など）は何も出力しない。
このストリームのデフォルト宛先はプログラムを起動した端末のディスプレイになっている。リダイレクトにより容易に宛先を変更できる。
標準出力のファイル記述子は1である。POSIXのcodice_3ではcodice_10と定義されている。対応するcodice_5での変数はcodice_12、codice_7での変数はcodice_14である。
標準エラー出力 (stderr).
標準エラー出力（, stderr）は、エラーメッセージや診断メッセージを出力するためのもう1つの出力ストリームである。標準出力とは独立しているため、一方だけをリダイレクトすることができる。デフォルトでは端末（のディスプレイ）になっており、標準出力がリダイレクトされていて画面に表示されなくとも、エラーメッセージだけはユーザーが目にするようになっている。例えば、パイプで出力が他のプログラムの入力に接続されている場合でも、標準エラー出力は直接端末のディスプレイに届く。
標準出力と標準エラー出力を同じ出力先（端末など）にリダイレクトすることもよくある。バッファが関与しない場合、メッセージはプログラムが書いた順序で現れる。典型的な例として、標準エラー出力がバッファリングされておらず、標準出力が行単位でバッファリングされている場合、後から標準エラー出力に書かれたメッセージが先に端末上に表示されることがある（標準出力のバッファが満杯になっていない場合）。
標準エラー出力のファイル記述子は2である。POSIXのcodice_3ではcodice_16と定義されている。対応するcodice_5での変数はcodice_18、codice_7での変数は2つありcodice_20とcodice_21である。前者はバッファリングされておらず、後者はC++の他のストリームと同様にバッファリングされている。
歴史.
1950年代: FORTRAN.
FORTRANにもUNIXのようなファイル記述子があり、codice_22がstdin、codice_23がstdoutを表す。
! FORTRAN 77 example
 PROGRAM MAIN
 READ(UNIT=5,*)NUMBER
 WRITE(UNIT=6,'(F5.3)')' NUMBER IS: ',NUMBER
 END
1960年: ALGOL 60.
ALGOL 60には、標準ストリーム（ファイルアクセス）の概念が存在しない。
1968年: ALGOL 68.
ALGOL 68では、入力 (input) と出力 (output) をあわせてtransputと呼ぶ。Cornelis H. A. Kosterは"transput"標準を定義した。この標準にはcodice_24、codice_25、codice_26、codice_27がある。
例: 
1970年代: CとUnix.
C言語では、stdin、stdout、stderrのストリームはUnixのファイル記述子 0、1、2にそれぞれ対応する。
1995年: Java.
Javaでは、標準ストリームは (stdin)、 (stdout)、 (stderr) で参照される。
public static void main(String args[]) {
 try {
 BufferedReader br = 
 new BufferedReader(new InputStreamReader(System.in));
 String s = br.readLine();
 double number = Double.parseDouble(s);
 System.out.println("Number is:" + number);
 } catch (Exception e) {
 System.err.println("Error:" + e.getMessage());
2000年代: .NET.
C#などの.NET言語では、標準ストリームはcodice_28 (stdin)、codice_29 (stdout)、codice_30 (stderr) で参照される。stdinおよびstdoutストリームの基本的な読み書きの場合、クラスcodice_31を使って直接アクセスすることもできる（つまり、codice_32の代わりにcodice_33を使える）。
codice_28、codice_29、codice_30は codice_37 (stdin) および codice_38 (stdout, stderr) オブジェクトであり、テキストベースの標準ストリームにしかアクセスできない。標準ストリームへの完全バイナリアクセスにはcodice_39オブジェクトを使う必要があり、それぞれcodice_40、codice_41、codice_42で得られる。
// C# example
public static int Main(string[] args)
 try {
 string s = System.Console.In.ReadLine();
 double number = double.Parse(s);
 System.Console.Out.WriteLine("Number is: {0:F3}", number);
 return 0;
 // If Parse() threw an exception
 } catch (System.ArgumentNullException) { 
 System.Console.Error.WriteLine("No number was entered!");
 } catch (System.FormatException) {
 System.Console.Error.WriteLine("The specified value is not a valid number!");
 } catch (System.OverflowException) {
 System.Console.Error.WriteLine("The specified number is too big!");
 return -1;
' 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(s)
 System.Console.Out.WriteLine("Number is: {0:F3}", number)
 Return 0
 Catch e As System.InvalidCastException
 ' if CDbl() threw an exception
 System.Console.Error.WriteLine("No number was entered!")
 Return 1
 End Try
End Function
codice_43クラスを使うと、そのインスタンスプロパティcodice_44、codice_45、codice_46を使ってそのプロセスの標準ストリームにアクセスできる。
GUI.
グラフィカルユーザインタフェース (GUI) では滅多に標準ストリームを使わない。当然、GUIプログラムをリダイレクトしたり、GUIプログラムでパイプを使うことはない。GUIにとって標準ストリームに近いのはコピー・アンド・ペーストであろう。しかし、ユーザーの操作を必要とするため、多数の「ペースト」を行うのは効率的ではない。特筆すべき例外としてdwmというタイル型ウィンドウマネージャでは、stdout上のデータをステータスバーに直接表示する。
特にUnix系の一部のGUIプログラムは、デバッグ情報を標準エラー出力に書き込んでいることがある。また、標準入力にファイルを指定する形式で働くものもあり、Unix系のメディアプレーヤーに多い。
では、GUIを構築するインタプリタ型プログラムとのインタフェースにstdinを使うことができる。