アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下のURLのベストアンサーの回答で、ストリームの意味と、なぜハードディスクだったら、非常に時間がかかるのでしょうか? それともう一つのURLの関数の所のファイル、メモリ、標準入出力の所を教えて頂けると幸いです。
https://detail.chiebukuro.yahoo.co.jp/qa/questio …
もう一つのURLです。
https://zenn.dev/masahiro_toba/books/a7d0c3d685a …
教えて頂けると幸いです。
すみません。以下の文章で、バッファを使わない時は、プログラムから1文字出力してファイルに書き込むことを繰り返します。書き込み先がハードディスクだったら非常に時間がかかるでしょう。というのは、つまり、プログラムから1文字だけ出力したものをファイルに書き込んで、その1文字だけ出力したファイルをハードディスクにいちいち保存するのでは、非常に時間がかかるという事でしょうか?教えて頂けると幸いです。

A 回答 (4件)

ご質問は難しすぎて過ぎて私には正確に理解することができません。

お尋ねになっていることは「大体この辺かな...」の想像の基で回答することをお許しください。

1.ストリームの意味...
ご質問者様がHDD上に置かれたファイルを読み取るプログラムを作成するとしましょう。プログラムは以下のようになるでしょうか...

include <stdio.h>

int main ( void )
{
FILE *fp = fopen ( "/etc/passwd", "r" );
int dat = 1;
while ( EOF != dat ) {
   dat = fgetc ( fp );
   printf ( "%c", dat );
   }
fclose ( fp );
return ( 0 );
}

私のパソコンでは"/etc/passwd"ファイルはHDD上に置かれています。しかしながら"passwd"ファイルを指定するのに「何番目のHDDの、さらに何番目のパーティションの...」等というパソコンのハードウエア上の機器の指定をしていないことにご注目ください。単純にファイルシステム上の"/etc/passwd"と指定するだけで、自動的にHDDの番号、パーティションの番号などは決定されます。
つまりこの時点で既にファイルの指定が"抽象化"されていることにご注意ください。

さて、fopen ()関数でオープンしたファイルですが、fgetc ()関数により1バイトづつ読み取られることになります。

ここでご質問者様は読み取られるデータが辿る経路をご存知ですか。HDDはガラスの円盤が高速で回転し、データ読み取りのアームが左右にガチャンガチャンと動いて読み取ります。
データはHDD基板上の様々なチップを経由して、HDDが接続されているマザーボードに繋がるSATAケーブルの何処かのピンを通じてマザーボードに転送されるんでしょうね。マザーボードに移動したデータは、ボード上に張り巡らされた配線のどれかを通じ、更に様々なチップを経由して初めてCPUに届き、上記のプログラムで利用できることになります。
私が言いたいのは「HDD上のデータを読み取るだけでも、データは複雑なハードウエア上の機器を経由してプログラムに届けられる。」ということなのですが、通常プログラムを作る上で、HDD上の何処かに書き込まれたデータがどのような経路でCPUの、作成したプログラムに提供されるのか考える人は居ません、さらに考える必要もありません。
それはデータが経由する経路を抽象化した(単純化した)ストリームと考えれば充分だからです。だからストリームは次のようなごく単純な絵にすることもできます...

  \_________________/
*fp ←←←←←←←←←← File: /etc/passwd
  /-----------------\
     Stream

プログラマは前述の"*fp"を取得しさえすれば、ファイル"/etc/passwd"に対して自由にデータを読み書きできますね。"*fp"さえ取得すればファイルがハードウエアの何処にあるか気にする必要は無いのです。

2.ストリームバッファ
前項でご説明したHDD(ハードディスク)ですが、データを1バイトづつ読んだり書いたりするのは不効率で大変遅いのです。何故ならいちいち読み取り(書き込み)アームをガチャンガチャンと動かさなければならないからです。
ところが一度に数千バイトのデータを纏めて読み書きするのはある程度早いのです。それは読み取り(書き込み)アームを同じ場所に固定しておけば良いからです。
ところでご質問者様もコンピュータが利用するストレージ(記憶装置)と呼ばれるものの多くはHDDと同様、回転する円盤と左右に動くアーム機構を備えていることをご存知でしょう...

●フロッピー
●HDD
●DVD
●CD

これら全部が回転円盤+とろとろ遅いアーム方式です。
ですから上記のどれもHDDの欠点を多かれ少なかれ同じように持っています。そこで「一度に数千バイトのデータを纏めて読み書きするのはある程度早い...」に着目した新たな機能がストリームバッファです。

  \_________________/
     ↓←←←←← File: /etc/passwd
*fp ←←←+←←
  /----+↓ ↑+------\
     |↓ ↑|
     |↓ ↑|
     |→→↑|
     --------
     Stream
     Buffer

a: fgetc ()関数の実行で、バッファが一杯になるまでデータを読んでしまう。但しプログラムが受け取るのは先頭の1バイトだけ。
b: 2回目以降のfgetc ()関数の実行では、HDDにアクセスせずにバッファから1バイトデータを提供する...

  \_________________/
*fp ←←←←←←
  /----+  ↑+------\
     |  ↑|
     |↓ ↑|
     |→→↑|
     --------
     Stream
     Buffer

c: バッファが空になるまで、HDDにアクセスせずにバッファから1バイトデータを提供する。
d: バッファが空になったら、もう一度バッファが一杯になるまでデータを読んでしまう。プログラムが受け取るのは先頭の1バイトだけ。
以下は同じ手順が繰り返されます。

3.ストリームバッファの必要性
最近のストレージ機器(HDD/DVD/CD..)ではストリームバッファの必要性は薄れています。
プログラムを作成する際にバッファを使っているかどうか意識する必要性はほとんどありません。
何故ならそれぞれの機器に独自で「バッファやキャッシュメモリ」と呼ばれる、ストリームバッファに相当する機能を内蔵しているからです。各機種のカタログを参照すると、多くは「メモリ16Mb」などと書いているのがそれです。

但し、私自身の経験では3.5"フロッピードライブだけはこのようなメモリ機能を持っていません。今でもUSB接続のフロッピーは千円ぐらいで手に入るかもしれませんが、安いのでお試しください。
ストリームバッファ無しの状態でデータの読み書きをすると、1Mb程度のデータを読み書きするのに"30分"程もかかります。その間ずっと呑気に「ガチャガチャ」音がすることになります。
    • good
    • 0

今時のOSは、キャラクタデバイスやファイルやキーボートやコンソ―ル出力のI/Oに統一されたインターフェースを提供するけど、それをストリームとは呼ばないだろうから、ストリームという言葉の使用は不適切だね。



ストリームはC++でキャラク夕デバイスやファイルやキーボードやコンソ―ル出力の入出力の操作を抽象化したもの。
現在ではJavaやc#等でも使える抽象化されたインターフェースです。

これとバッファリングはまた別の話
    • good
    • 0

>つまり、プログラムから1文字だけ出力したものをファイルに書き込んで、その1文字だけ出力したファイルをハードディスクにいちいち保存するのでは、非常に時間がかかるという事でしょうか?


質問者さんんがこの解釈で納得されるなら、この解釈でOKと思います
    • good
    • 0

「ストリーム」は流れを意味する言葉で、次々と新しいデータがくる入出力I/Fの抽象化です。

入力なら読むたびに次(の文字ないし行)が入力され、出力なら書くたびに次(の文字ないし行)が出力されます。
ファイルはもちろんストリームではありません。でも今どこまで読み/書きしたか覚えておいて次はその続きを読み/書きすることでストリームを模擬できるのでそのようにされています。
ストリームは1文字や1行の単位で読み/書きできますが、ハードディスクのようなディスクデバイスはブロックデバイスであり、ブロック単位でしか読み書きできません。ブロックは古くは1セクタ=512バイトでしたが、最近は4Kバイトが最小単位でしょうか。OSやファイルシステムによっては最小単位がもっと大きな場合もあります。
従ってバッファを使わない場合というのは実際にはありません。プログラムが例え1バイト単位で読んだとしても、OSドライバのレベルで1ブロックをバッファ(通常メインメモリ上にある)に読み込んでから1バイトをプログラムが管理するメモリにコピーして返すことになります。
ただしバッファをプログラムで扱わない場合には、プログラムの呼び出しの間に他からファイルが書き換えられるリスクを考えると1バイト読むたびに裏では1ブロック読み込まれるという動作になり、非常に時間がかかる可能性があります。書き込みでも同様です。
    • good
    • 0
この回答へのお礼

もう少し詳しく教えて頂けると幸いです。

お礼日時:2023/11/01 20:51

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A