web-dev-qa-db-ja.com

ストリームの概念を説明できますか?

ストリームはバイトシーケンスの表現であることを理解しています。各ストリームは、指定されたバッキングストアに対してバイトを読み書きする手段を提供します。しかし、ストリームのポイントは何ですか?なぜバッキングストア自体が私たちと対話しないのですか?

なんらかの理由で、このコンセプトは私にはクリックされません。たくさんの記事を読みましたが、アナロジーか何かが必要だと思います。

179
Rob Sobers

「ストリーム」という言葉が選ばれたのは、それが(実際に)それを使用するときに伝えたいものと非常に似た意味を表すからです。

バッキングストアについて少しだけ忘れて、水流の類推について考え始めましょう。川を水が連続して流れるように、データの連続的な流れを受け取ります。データがどこから来たのかを必ずしも知る必要はありません。ほとんどの場合、その必要はありません。ファイル、ソケット、またはその他のソースからのものであっても、実際には問題ではありません(すべきではありません)。これは水の流れを受け取ることに非常に似ており、水がどこから来ているのかを知る必要はありません。それは湖、噴水、または他のソースからのものであっても、それは実際には問題ではありません(そうではありません).

つまり、必要なデータの取得にのみ関心があると考え始めると、それがどこから来たのかに関係なく、他の人が語った抽象化がより明確になります。ストリームをラップできると考え始めると、メソッドは完全に機能します。たとえば、これを行うことができます:

int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }

// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);

int x = ReadInt(reader);

ご覧のとおり、処理ロジックを変更せずに入力ソースを簡単に変更できます。たとえば、ファイルではなくネットワークソケットからデータを読み取るには:

Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);

できる限り簡単です。ストリームの「ラッパー」を構築できる限り、あらゆる種類の入力ソースを使用できるため、美しさは継続します。あなたもこれを行うことができます:

public class RandomNumbersStreamReader : StreamReader {
    private Random random = new Random();

    public String ReadLine() { return random.Next().ToString(); }
}

// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());

見る?メソッドが入力ソースを気にしない限り、さまざまな方法でソースをカスタマイズできます。この抽象化により、非常にエレガントな方法で入力を処理ロジックから分離できます。

自分で作成したストリームにはバッキングストアはありませんが、目的を完全に果たしていることに注意してください。

したがって、要約すると、ストリームは入力の単なるソースであり、別のソースを隠します(抽出します)。抽象化を壊さない限り、コードは非常に柔軟になります。

227
Hosam Aly

重要なのは、バッキングストアが何であるかを知る必要はないということです-それはそれに対する抽象化です。確かに、beバッキングストアさえないかもしれません-ネットワークから読み取ることができ、データがまったく「格納」されることはありません。

ファイルシステム、メモリ、ネットワーク、またはストリームのアイデアをサポートする他の何かと通信していても機能するコードを作成できれば、コードはより柔軟になります。

さらに、多くの場合、ストリームはチェーン化されます-入れたものをすべて圧縮して、圧縮されたフォームを別のストリームに書き込んだり、データを暗号化するなどのストリームを作成できます。チェーン、復号化、圧縮解除など。

37
Jon Skeet

ストリームの目的は、ユーザーとバッキングストアの間に抽象化レイヤーを提供することです。したがって、ストリームを使用する特定のコードブロックは、バッキングストアがディスクファイル、メモリなどであるかどうかを気にする必要はありません。

30
Torlack

それは小川のことではなく、水泳のことです。 1つのストリームを泳ぐことができる場合、遭遇するストリームを泳ぐことができます。

11
dmajkic

エコーチャンバーに追加するために、ストリームは抽象化されているため、基になるストアは気にしません。ストリームを使用するシナリオと使用しないシナリオを検討する場合に最も意味があります。

ストリームは、私がよく知っている非ストリームベースの方法をはるかに上回っているので、ファイルはほとんど面白みがありません。インターネットファイルから始めましょう。

インターネットからファイルをダウンロードしたい場合、TCPソケットを開いて接続し、バイトがなくなるまでバイトを受信する必要があります。バッファを管理する必要があります。予想されるファイルのサイズ、および接続が切断されたことを検出し、これを適切に処理するコードを記述します。

ある種のTcpDataStreamオブジェクトがあるとします。適切な接続情報を使用して作成し、それ以上バイトがなくなるまでストリームからバイトを読み取ります。ストリームは、バッファ管理、データ終了条件、および接続管理を処理します。

このようにして、ストリームによりI/Oが簡単になります。確かに、ストリームが行うことを行うTcpFileDownloaderクラスを作成できますが、TCPに固有のクラスがあります。ほとんどのストリームインターフェイスは、単にRead()およびWrite()メソッドを提供し、より複雑な概念は内部実装によって処理されます。このため、同じ基本コードを使用して、メモリ、ディスクファイル、ソケット、および他の多くのデータストアを読み書きできます。

7
OwenP

初めてストリーミングについて聞いたとき、それはウェブカメラでのライブストリーミングのコンテキストでした。そのため、一方のホストがビデオコンテンツをブロードキャストしており、もう一方のホストがビデオコンテンツを受信して​​います。これはストリーミングですか?うーん...はい...しかし、ライブストリームは具体的な概念であり、質問はストリーミングの抽象的な概念を指していると思います。 https://en.wikipedia.org/wiki/Live_streaming を参照してください

それでは先に進みましょう。


ストリーミングできるリソースはビデオだけではありません。サウンドをストリーミングできます。それで、私たちは今ストリーミングメディアについて話している。 https://en.wikipedia.org/wiki/Streaming_media を参照してください。それでは、いくつかのデータ配信方法を互いに比較しましょう。

クラシックファイルのダウンロードはリアルタイムでは発生しません。ファイルを使用する前に、ダウンロードが完了するまで待つ必要があります。

プログレッシブダウンロードを使用すると、ビデオファイルをダウンロードしながら視聴できます。早送りと巻き戻しが可能です。そのためには、ビデオファイルを受信するコンピューターのメモリにデータを一時的に保存するバッファーを使用します。データがチャンク化されていても、実際のストリーミングではありません。

ストリーミングリアルタイムで発生し、データをチャンクします。ストリーミングはライブブロードキャストで実装されます。ブロードキャストを聞いているクライアントは、早送りや巻き戻しができません。ビデオストリームでは、データは再生後に破棄されます。

Streaming Serverはクライアントとの双方向接続を維持し、Web Serverはサーバーの応答後に接続を閉じます。


ストリーミングできるのはオーディオとビデオだけではありません。 PHPマニュアルでストリームの概念を見てみましょう。

ストリームは、ストリーミング可能な動作を示すリソースオブジェクトです。つまり、readからまたはに書き込むことができますそして、ストリーム内の任意の場所にfseek()できる場合があります。

PHPでは、リソースは、ファイル、データベース接続などの外部ソースへの参照です。つまり、ストリームは読み取りまたは書き込み可能なソースです。したがって、fopen()を使用した場合、すでにストリームを使用しています。

テキスト、オーディオ、Zipファイルもストリーミングできます。さらに、ストリーミングはファイルに限定されません。 HTTP、FTP、SSH接続および入出力も同様にストリーミングできます。


ウィキペディアはストリーミングの概念について何と言っていますか?

コンピューターサイエンスでは、ストリームは時間の経過とともに利用可能になる一連のデータ要素です。ストリームは、大規模なバッチではなく、コンベアベルト上のアイテムが1つずつ処理されると考えることができます。

参照: https://en.wikipedia.org/wiki/Stream_%28computing%29 .

ウィキペディアはこれにリンクしています: https://srfi.schemers.org/srfi-41/srfi-41.html と作家はストリームについてこう言っています:

ストリームは、レイジーリストとも呼ばれ、オンデマンドでのみ計算される要素を含むシーケンシャルデータ構造です。ストリームはヌルであるか、cdrにストリームがあるペアです。ストリームの要素はアクセス時にのみ計算されるため、ストリームは無限になります。

したがって、ストリームは実際にはデータ構造です。


私の結論:ストリームとは、シーケンシャルに読み書きできるデータを含むことができるソースです。ストリームは、ソースに含まれるすべてを一度に読み取るのではなく、順次読み取り/書き込みを行います。


便利なリンク:

  1. http://www.slideshare.net/auroraeosrose/writing-and-using-php-streams-and-sockets-zendcon-2011 非常に明確なプレゼンテーションを提供
  2. https://www.sk89q.com/2010/04/introduction-to-php-streams/
  3. http://www.netlingo.com/Word/stream-or-streaming.php
  4. http://www.brainbell.com/tutorials/php/Using_PHP_Streams.htm
  5. http://www.sitepoint.com/php-streaming-output-buffering-explained/
  6. http://php.net/manual/en/wrappers.php
  7. http://php.net/manual/en/intro.stream.php
  8. http://www.digidata-lb.com/streaming/Streaming_Proposal.pdf
  9. http://www.webopedia.com/TERM/S/streaming.html
  10. https://en.wikipedia.org/wiki/Stream_%28computing%29
  11. https://srfi.schemers.org/srfi-41/srfi-41.html
4
Julian

それは単なる概念であり、人生を楽にする別の抽象化レベルです。そして、それらはすべて共通のインターフェースを持っているので、それらをパイプのように組み合わせることができます。たとえば、base64にエンコードし、次にZipしてから、これをディスクにすべて1行で書き込みます。

4
vava

私が使用するビジュアライゼーションはコンベアベルトです。私はそれについて何も知らないので実際の工場ではなく、アイテムが線に沿って移動し、一連のダムデバイスによってスタンプおよびボックス化され、カウントされ、チェックされる漫画工場です。

たとえば、ケーキにチェリーをつけるデバイスなど、1つのことを行う単純なコンポーネントがあります。このデバイスには、チェリーのないケーキの入力ストリームと、チェリーのあるケーキの出力ストリームがあります。この方法で処理を構造化することに言及する価値がある3つの利点があります。

まず、コンポーネント自体を簡素化します。ケーキにチョコレートのアイシングを施したい場合は、ケーキに関するすべてを知っている複雑なデバイスは必要ありません。チョコレートのアイシングをそれに入れるものに貼り付けるダムデバイスを作成できます(漫画では、次のアイテムがケーキではないことを知らない限り、Wile E. Coyoteです。

次に、デバイスを異なるシーケンスに配置することにより、異なる製品を作成できます。たぶん、アイシングの上にチェリーの代わりにチェリーの上にアイシングを付けたい場合は、ライン上でデバイスを交換するだけでできます。 。

第三に、デバイスはインベントリ、ボックス化、またはボックス化解除を管理する必要がありません。物を集約してパッケージ化する最も効率的な方法は変更可能です:多分今日は48個の箱にケーキを入れてトラックで配達しますが、明日はカスタムオーダーに応じて6個の箱を送りたいと考えています。この種の変更は、生産ラインの開始時と終了時にマシンを交換または再構成することで対応できます。行の中央にあるチェリーマシンは、一度に異なる数のアイテムを処理するために変更する必要はありません。常に一度に1つのアイテムで動作し、その入力または出力がどのようであるかを知る必要はありません。グループ化されています。

4
user8599

私が見たストリームの最良の説明は SICPの3章 です。 (意味を理解するために最初の2つの章を読む必要があるかもしれませんが、とにかくすべきです:-)

バイトにはステラムを使用せず、整数に使用します。私が得た大きなポイントは次のとおりです。

  • ストリームは遅延リストです
  • (場合によっては事前にすべてを熱心に計算する)計算オーバーヘッドはとんでもないです
  • ストリームを使用して、無限に長いシーケンスを表すことができます
3
Ken

別のポイント(ファイルの読み取り状況の場合):

  1. streamは、finished reading all content of the file
  2. すべてのファイルコンテンツを一度にロードする必要がないため、メモリを節約できます。
2
vikyd

ストリームは、データ(バイト、文字など)の抽象的なソースと考えてください。これらは、ネットワークソケット、ディスク上のファイル、またはWebサーバーからの応答など、具体的なデータソースの読み取りと書き込みの実際のメカニズムを抽象化します。

1
Anton Gogolev

バッキングストア自体は多くの場合、単なる別の抽象化であると考える必要があると思います。メモリストリームは非常に理解しやすいですが、ファイルは使用しているファイルシステムによって根本的に異なります。使用しているハードドライブは気にしません。実際、すべてのストリームがバッキングストアの上にあるわけではありません。ネットワークストリームはほとんどストリームにすぎません。

ストリームのポイントは、重要なことに注意を向けることです。標準的な抽象化により、一般的な操作を実行できます。たとえば、今日のファイルやHTTP応答でURLを検索したくない場合でも、明日を希望しないわけではありません。

ストリームは当初、メモリがストレージに比べて小さいときに考案されました。 Cファイルを読み込むだけでも大きな負荷になる可能性があります。メモリフットプリントの最小化は非常に重要でした。したがって、ロードする必要がほとんどない抽象化は非常に便利でした。今日では、ネットワーク通信を実行する際にも同様に有用であり、ファイルを扱う際にその制限がほとんどないことが判明しています。一般的な方法でバッファリングなどを透過的に追加できるため、さらに便利になります。

1
Julian Birch

短くしておきますが、ここでみことばを逃していました。

ストリームはキュー通常、あらゆる種類のデータを含むバッファに保存されます。

(今、私たちはすべてのキューが何であるかを知っているので、これについてこれ以上説明する必要はありません。)

0
Marcus

ストリームは、バイトシーケンスの抽象化です。アイデアは、バイトがどこから来たのかを知る必要はなく、標準化された方法でそれらを読むことができるということです。

たとえば、ストリームを介してデータを処理する場合、データがファイル、ネットワーク接続、文字列、データベース内のblobなどからのものであるかどうかはコードにとって重要ではありません。

バッキングストアの実装に結び付けられるという事実を除いて、バッキングストア自体とやり取りすること自体に問題はありません。

0
Sean

ストリームは、データと対話するためのメソッドとプロパティの標準セットを提供する抽象化です。実際のストレージメディアから抽象化することにより、そのメディアが何であるか、またはそのメディアの実装に完全に依存することなく、コードを記述できます。

良い例えは、バッグを考えることです。バッグがバッグであるという仕事を実行し、アイテムを取り戻すことができる限り、バッグが何で作られているか、または荷物を入れるときに何をするかは気にしません。ストリームは、ストレージメディアに対して、バッグのさまざまなインスタンス(ゴミ袋、ハンドバッグ、リュックサックなど)のバッグの概念が定義するもの-相互作用のルールを定義します。

0
Jeff Yates