= ストリーム

¥chapter{ストリーム}

ストリームは、バイトデータの読み書きをシーケンシャル（順序通り）に行うデータ構造です。読み書きされたバイトデータは、ファイルやソケットであり、外部プログラムとの間を送受信されます。Konoha では、入力ストリームと出力ストリームをそれぞれ読み込み、書き込み専用のストリームとして分離し、InputStreamクラスとOutputStreamクラスとして提供しています。

% さて、文字コードの問題が少々あらわれます。Konohaの InputStreamと OutputStreamは、C言語由来の低水準APIをメソッドをサポートしています。同時に、文字列のエンコーディングを変換しながら入出力する高水準APIもメソッドとしてサポートしています。

== 標準ストリーム}

Konohaは、システム定数 IN|, OUT|, ERR| を通して、標準入力(stdin)、標準出力(stdout), 標準出力(stderr)にそれぞれ相当する各種ストリームオブジェクトが得られます。

{{{
>>> OUT
"/dev/stdout"
>>> OUT.println("hi");
hi
}}}

また、それぞれのストリームのデフォルト値として、"/dev/null"|に相当するストリームを持っています。これらは、何のデータも読み込めないし、何のデータも書き込めない特別なストリームです。

{{{
>>> out = default(OutputStream);
>>> out
"/dev/null"
>>> out.println("hi");             // 何も出力されない
>>> 
}}}

=== 生成}

新しいストリームは、InputStreamもしくはOutputStreamクラスのコンストラクタにリソース名を与えて生成する。何らかの理由でストリームが生成できない場合は、IO!!|例外がスローされます。

{{{
in = new InputStream("file.txt");
foreach(String line from in) {
	print line;
}
in.close()
}}}

入力ストリームの種類は、リソース名から自動的に判断されます。Konoha は、下記のリソース以外にもストリームドライバーをインストールすることで、種類を拡張することができます。

¥begin{itemize}
¥item{¥bf ファイル} --- ファイルパス（ファイル名）を与えるし、もしくは明示的にfile:|タグをリソース名の先頭につける。
¥item{¥bf WEBリソース} --- URLを与える。ちなみに、これは http:| タグで始まるリソース名となっています。
¥end{itemize}

また、文字列やバイト列など、内部リソース(メモリ）をストリームとして抽象化する扱うこともできます。これは、マップキャスト演算子を用いて入力ストリームを得ることで生成する。

{{{
>>> String data = "naruto";
>>> in = (InputStream)data;
>>> in.getc();


}}}

注意：文字列は、UTF8でエンコーディングされたバイトストリームとして扱われます。

=== データの読み込み}

入力ストリームは、バイト列です。バイトは、Konoha では、0から255までの整数で表現されます。InputStreamクラスは、C言語に由来する低水準な読み込みメソッドを備えています。

ひとつは、1バイトずつ読み込む getc()|メソッドです。正しくストリームから読めた場合は、0~255 の値を返すか、もしストリームの終端に達した場合は、EOF を返す。

{{{
>>> InputStream in;
>>> while(ch = in.getc() != EOF) {
...   OUT << %c(ch);
... }
}}}

もうひとつは、read()|メソッドで、バッファ(byte[]})へ指定された指定されたバッファサイズ(buf|)分を一度に読み込むことができます。戻り値は、実際に読み込まれたサイズであり、0からバッファサイズまでのどれかの値となります。

{{{
>>> InputStream in;    
>>> byte[] buf = new byte[4096];
>>> while((in.read(buf) != 0) {
...   OUT << buf;
... }
}}}

=== テキストの読み込み}


=== 入力ストリームの終了}


== OutputStream} 出力ストリーム}

== ファイル}

== パイプ}

パイプは、プロセス間通信の最もシンプルで広く使われている方法です。Konoha では、UNIX(互換)パッケージを用いることで、InputStreamか OutputStreamのどちらをパイプに連結することができます。

パイプを識別するタグは、'pipe:'|, 'sh:'|, 'cmd:'| のどれかです。

=== 外部プログラムからデータを受ける}

パイプが最も活躍するシチュエーションは、外部のコマンド（プログラム）を起動し、その実行結果をえるときです。

次は、UNIX コマンド(ls)を実行し、その実行結果を1行ずつ表示するスクリプトの例です。Windows の場合は、ls コマンドがないので、代わりに dir で試してみましょう。

{{{
using unix.*;
in = new InputStream("pipe:ls -l");
foreach(line from in) {
  print line;
}
in.close()
}}}

=== 外部プログラムへデータを送信する}

パイプでは、InputStreamの代わりに、OutputStreamを用いれば、ストリームをとしてデータの送信が可能になります。

¥begin{comment}

パイプが最も活躍するシチュエーションは、外部のコマンド（プログラム）を起動し、その実行結果をえるときです。

次は、UNIX コマンド(ls)を実行し、その実行結果を1行ずつ表示するスクリプトの例です。Windows の場合は、ls コマンドがないので、代わりに dir で試してみましょう。

{{{
using unix.*;
in = new InputStream("pipe:ls -l");
foreach(line from in) {
  print line;
}
in.close()
}}}

¥end{comment}

== Socket}





[[include(KbookIndex)]]
[[include(KbookFooter)]]

