1. ホーム
  2. java

[解決済み] ストリームの概念を説明できますか?

2022-04-22 09:08:13

質問内容

ストリームとは、バイト列の表現であると理解しています。 各ストリームは、与えられたバッキングストアにバイトを読み書きするための手段を提供します。 しかし、ストリームのポイントは何でしょうか? なぜバッキングストアそのものを操作するのではないのでしょうか?

なぜか、このコンセプトは私にはピンとこないんです。 たくさんの記事を読みましたが、例え話か何かが必要なようです。

どのように解決するのか?

ストリームという言葉が選ばれたのは、私たちが伝えたいことと(実際の生活で)非常によく似た意味を表しているからです。

バッキングストアのことは少し忘れて、水の流れに例えて考えてみましょう。川で水が絶え間なく流れているように、あなたも絶え間なくデータを受け取っています。データがどこから来るのか、知る必要はありません。ファイルやソケット、その他のソースであっても、それは重要ではありません(はず)。これは、水の流れを受け取るのと非常に似ていて、水がどこから来るのか知る必要はありません。それが湖であろうと、噴水であろうと、その他の源であろうと、それは本当に重要ではない(はず)です。

とはいえ、どこから来たかに関係なく、必要なデータを得ることだけを考えるようになると、他の人が言っていた抽象的な表現がより明確になります。ストリームをラップしても、メソッドは完璧に動作すると考えるようになるのです。例えば、こんな感じです。

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());

ほらね。あなたのメソッドが入力ソースを気にしない限り、様々な方法でソースをカスタマイズすることができます。抽象化することで、入力と処理ロジックを非常にエレガントな方法で切り離すことができます。

なお、自作のストリームはバッキングストアを持たないが、それでも我々の目的には完全に合致している。

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