- ベストアンサー
Java ストリームをわかりやすく教えてください
Javaを独学で学んでいる初心者です。 ストリームの意味がよくわからなく困っています。 参考書には「入出力機能を支えている概念がストリーム」と書いてあるのですが意味が分かりません。 まだまだ勉強不足で知識が至らないので、簡単なたとえ話などで説明していただけると嬉しいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
バッファーという考えとセットになっていることが多いです。 というかほとんど差がないでしょう。 プログラムの処理とデータの流れで考えると ひとつ現実的な大きな問題が存在します。 プログラムの処理スピードに対して キーボード、ファイル(ディスク装置)、ネットワーク、 プリンター、画面などの入出力デバイスは 遅い、ということです。 また、プログラムでは1文字ずつほしいのに ある入力機器は数千文字単位ずつでしかデータを取得できない、 といったこともあります。 ですから、メモリ上に一時的にデータを蓄えておいて それを順にすこしずつ読み込む/出力する、 もしくは一気に読み込む/出力する ということをします。 そのバッファー、つまりデータの入力/出力の流れを プログラムでつなげるとどうでしょう。 ファイルを読み込んだデータをAプログラムで集計して Bプログラムで表形式にフォーマットして Cプログラムでメール送信してかつ、プリンターに出力する、 という処理を一気に行うことができます。 こういう連結は別途、パイプ と呼ぶこともありますが。 処理はプログラムでやるが 入出力機器からのデータの読み込みや出力は裏でOSがやる、 ということで生ずるタイミングやスピードなどのズレを どうやって補正するか、という問題の解決と それから派生して プログラムとプログラムをデータの流れで連結する、 という考えをまとめたのがストリームと 呼べなくもありません。 実生活でたとえてみましょう。 提出された申請書を確認してハンコを押して 別の事務所に郵送する、という業務があったとします。 ですが、申請書はいつ出されるかわかりませんので いつもそのためだけにじっと出されるのをまって机に ハンコをもって座っているのは非効率です。 また郵便で出すのもまとめて一気に出したほうがお得です。 ですから、 月曜から金曜の午前まで申請書を受け付けて溜め込んでおき、 午後に一気にハンコを押して 夕方にまとめて郵便に出すことにします。 申請書 → 受付 → 確認/ハンコ押し → 郵便処理 とデータと処理が流れていくわけです。 これにはデータを溜め込んでおいて一気に出す、 というバッファの考えも含まれています。 つまり、 データの入力/出力のタイミング/スピードがプログラムの処理と非同期で、 プログラム同士の連結が容易でかつ入力元、出力先が切り替え可能な データの流れ、 と言ったところでしょうか。
その他の回答 (1)
- kokucho81
- ベストアンサー率61% (157/255)
ストリームとは概ね、全ての言語で出てくる言葉ですね。 たしかに特にはじめてのプログラム言語としては聞きなれないことでしょう。 しかし、確実にnakayam7さんも含め、プログラムを知っている人、知らない人を含め、 ほとんど全ての人がそれを直感的に理解しています。 ここでは最も理解しやすい、「出力ストリーム」に絞って話しをしましょう。 まず出力ストリームの方から。 ストリームという言葉を消してみましょう。「出力」。 プログラムにおいて、出力とはどのようなものなのでしょうか。 Javaを学んでいるnakayama7さんなら、System.out.println("Hello・・・")など、 プログラムから「画面」に「出力」ことはおそらくすでに実行済みでしょう。 プログラムから「ファイル」へと「出力」することはやりましたか? まだ、やっていないかもしれませんね。 でも、Word、Excel、画像編集ソフトなど、「ファイル」へと「保存」することはきっとやったことが あるでしょう。 それが、「プログラムか」ら「ファイル」への「出力」です。 プリンタは持っていらっしゃいますか? ブラウザなどの結果を印刷したことなどあるかもしれませんね。 これは「プログラム」から「プリンタ」への「出力」です。 以上のことを踏まえて、われわれは、潜在的に以下のようなことを 直感的に理解しているのです。 出力経路 = 画面; # 出力経路として「画面」を代入 println(出力経路, "HelloWorld"); # 画面へと出力される。 出力経路 = ファイル; # 出力経路として「ファイル」を代入 println(出力経路, "HelloWorld"); # ファイルへと出力される。 出力経路 = プリンタ; # 出力経路として「プリンタ」を代入 println(出力経路, "HelloWorld"); # プリンタへと出力される。 「経路」などと言われると、ちょっと抽象的ですが、 プログラム内の「データ」が、この何か「経路」的なものを通って、 画面に表示されたり、プリンタに印刷されるのだ(ろう)ということは 直感的に理解されていることでしょう。 この「経路」を、「ストリーム」と称しています。 ここまでわかれば、「『ストリーム』にデータを流す」「ストリームに流れてるデータ」といった 表現がされるであろうことが想像が付くことでしょう。 「入力ストリーム」は逆の流れですね。 ファイルからプログラムに読み込んだり、 キーボードから入力したものを、プログラムで読み込む際も、 何らかの「経路」的なものをデータが通って、プログラムに入ってくることは なんとなくは、理解できることでしょう。 さて、では、そもそもなぜ、このような「ストリーム」などという概念を プログラムに導入する必要があるのでしょう? 先ほど、 ================================================= 出力経路 = 画面; # 出力経路の出先として「画面」を代入 println(出力経路, "HelloWorld"); # 画面へと出力される。 出力経路 = ファイル; # 出力経路の出先として「ファイル」を代入 println(出力経路, "HelloWorld"); # ファイルへと出力される。 出力経路 = プリンタ; # 出力経路の出先として「プリンタ」を代入 println(出力経路, "HelloWorld"); # プリンタへと出力される。 ================================================= このように記載しました。 ここから想像が付くのは、「出力経路」という、プログラムから外方向へと流れる「経路」に 「画面」や「ファイル」や「プリンタ」など出先を切り替えることが出来ました。 しかし、実際に出力する時には、 ================================================= println(出力経路, "HelloWorld"); ================================================= と同じ記述で済ませています。 すなわち、出先を「画面」や「ファイル」や「プリンタ」といったように まるで「チャンネル」でも切り替えるかのように、パチパチ切り替えることが出来るのに、 実際の出力時の記述は「同じ」か、少なくとも、似たような記述で済ませられることがわかります。 まるで、「画面」や「ファイル」や「プリンタ」を、 「2チャンネル」「5チャンネル」「8チャンネル」であるかのように、 パチパチときりかえれるのに、実際にそのチャンネルが何なのかは、 ================================================= println(出力経路, "HelloWorld"); ================================================= といったように、特に意識しなくても良いのです。 実際には、プログラム言語によっては、「チャンネル」が変化してしまうと、 記述を変えなければならないものもありますが、 「ストリーム」という概念をプログラムへと導入している最も大きな理由、 そして、目指しているところはこのようなことなのです。 以上、参考になりましたら。