準・究極の選択

ストリームは入出力装置へのアクセスのための情報を抽象化した抽象データ型だそうですが(Wikipediaより)、それは具体的にどうなっているのですか?FILE構造体のようなものでしょうか。
・ストリームにはどんな情報が入っているのですか?
・ストリームはどこに展開されているのですか?メモリでしょうか。
あと、プログラミングは初心者なのでチンプンカンプンな質問をしているかも知れません。その場合は「何か勘違いしてますよ~」と指摘してくださると嬉しいです。回答お待ちしています。

A 回答 (4件)

>ストリームは入出力装置へのアクセスのための情報を抽象化した


>抽象データ型だそうですが(Wikipediaより)

まったくもって、そのとおりです。
"抽象"化された"概念"にすぎません。
”どこに?”なんて気にしてはいけません。
というか
気にしないでプログラミングできるのが素晴らしいところなのです。

しかし、"ストリーム"は完全に概念なので
実際には
ファイル・ストリームなど
”ストリーム"を具体化したものを使います。

では、なぜ"ストリーム"など抽象化したものがあるのでしょう?
わかりにくいだけではないでしょうか?
具体的なファイル・ストリームなどがあれば十分ではないですか?

少し具体例をあげます。

私たちは、よく”ファイル"という言葉を持ちいます。
”ファイル"とは何でしょうか?
"ファイルに保存する"っていったいどこにどうやって保存するのでしょうか?
ハードディスクなら磁気的に記録されます。
CD-R等なら光学的にメディアの小さなピットに記録されています。
USBメモリならフラッシュメモリで、いわゆる普通のメモリと同様に扱えます。

あなたが、メモ帳のようなアプリケーションを作ったとします。
ユーザーがUSBメモリに格納するよう指示してきたとします。
あなたは、どうしますか?

”USBメモリはユーザーからは"リムーバブル"で
フロッピーなどと同様に見える。
しかし、実際は半導体メモリ。
セクタなんてなくて、アドレスで指定する必要があって.....”

非常に具体的です。
ある意味わかりやすいです。

でも、大変だと思いませんか?

非常に抽象的で、ある意味、曖昧模糊としてますが、
USB(たとえばe:)のルートに"A.txt"として保存する。

この方が非常に楽で便利だと思いませんか?
USB上のどこにどのように記録されるか
まったくブラックBOXで不安になるかも知れませんが、
OSやドライバを信頼し任せるのがいいと私は思います。
    • good
    • 0
この回答へのお礼

ストリームが統一してくれるからこちらは知る必要がないんですね。
ストリームについて勉強になりました。回答ありがとうございました!

お礼日時:2009/04/23 19:24

>具体的にどうなっているのですか?FILE構造体のようなものでしょうか。



具体的な実装の方法は処理系に依存する。簡単に言えば「具体的な中身はコンパイラごとに違う」って事。

>・ストリームにはどんな情報が入っているのですか?

入出力デバイスに対して入出力を行う為に必要最低限な情報が入っている。情報の中身は処理系に依存する。

>・ストリームはどこに展開されているのですか?メモリでしょうか。

どこに何が展開されるかは、処理系に依存する。

ぶっちゃけ「中身を知らなくても使えるようにするために抽象化しているのだから、中身は知らなくてもよい。知っても意味が無いし、コンパイラ1つ1つ中身が違うから、知ったところでどうしようもない」って事。

それとも「A社がBと言うOS上で動くように設計したCと言う名前が付いたC++では、ストリームの中身はこうなっていて、D社がEと言うOS上で動くように設計したFと呼ばれているC言語では、ストリームの中身はこうなっていて…」って説明が欲しいですか?(「欲しい」と言われても、各社の各コンパイラのストリームの中身についてすべて説明するのは不可能なので、説明はしませんけど)
    • good
    • 0
この回答へのお礼

ブラックボックスでいいんですね。
回答ありがとうございました!

お礼日時:2009/04/23 20:51

 Wikipediaのその解説について見てみた処、その内容はC++に関連した解説となっており、Cに関連した解説よりも、より抽象的で、難しい内容になっていますから、C++について理解していないと、読んでも何が書いてあるのかさっぱり理解できないと思います。


 その頁で言われる「抽象データ型」とは、C++で用いられる用語で、『データの具体的な構造によってではなく、インタフェースによって定義されると考えられる型』のことです。簡単に言うと『クラス型』のことです。
 C++では、入出力ストリームもクラス型のインスタンス(=オブジェクト)として表現し、そのオブジェクトと他のオブジェクトとの間でのメッセージのやり取りによって、プログラムの動作を実現します。
 入出力先の代表例として、キーボードやディスプレイやディスクなどの物理デバイスがあります。これらの物理デバイスのどれを使うにしても、データの入出力には共通した処理スタイルがあります。この共通処理部分を利用できるプログラムとして構築した論理デバイスがストリームの実体です。
 実際にストリームを使うときは、入力用または出力用のストリームオブジェクトを宣言することで、論理デバイスと物理デバイスを結びつけます。こうして両者の結びつきができると、あとはストリームオブジェクト名(cinやcoutなど)を使用するだけで、簡単にデータの入出力を行うことができるようになります。
 キーボードから入力を行う場合は、キーボードに結びついた入力ストリーム cin を使用しますが、ファイルから入力を行いたいと思ったら、そのような入力ストリーム(オブジェクト)を自分で宣言することにより、簡単にファイルからの入力を行うことができます。


#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>

const int BUFLEN = 128;

using namespace std;

int main(int argc, char* argv[])
{
 ifstream ifs(argv[1]); // ファイル(argv[1])と結びついた入力ストリーム ifs を宣言

 char buffer[BUFLEN];
 long nc = 0;
 logn nl = 0;

 while ( !ifs.eof() ) {
  ifs.getline( buffer, sizeof buffer, '\n' )
   if( !( ifs.eof() && strlen( buffer ) == 0 ) ) {
     nc += strlen( buffer );
     nl++;
     cout << buffer << endl;
   }
  }
  cout << endl << endl << "Total characters : " << nc;
  cout << endl << "Number of lines : " << nl << endl;

  return 0;
}
    • good
    • 0
この回答へのお礼

具体的ですね!C++もいずれはと思っているのですが、まだまだそこまで追いつけません。直接ストリームを扱う方法もあるんですね。詳しい回答ありがとうございました!

お礼日時:2009/04/23 20:41

入出力を行う対象が何か、によってどんな情報が必要かは違ってきます。


たとえばファイルを読み出すストリームであれば、ごくごく単純にはファイルの識別子と「次にデータを読み出す位置は先頭から何バイト目か」という情報だけ持っていれば足りるかもしれません。読み出すべきデータはファイルの中にあるので、どこかに展開しておく必要はありません。
ただし、実際には1バイト~数バイトの単位でファイルを読み出すのは効率が悪いので、性能を考えてもっと複雑な作りになっているでしょう。
    • good
    • 0
この回答へのお礼

装置によって違うんですか。
わかりました。回答ありがとうございました!

お礼日時:2009/04/23 19:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報