ストリームを使用するC#


116

ストリームは私にとって一種の神秘的です。いつどのストリームをどのように使用するかわかりません。誰かがストリームの使用方法を説明できますか?

私が正しく理解していれば、3つのストリームタイプがあります。

  • stream
  • read stream
  • write stream

これは正しいです?そして、例えば、の違いは何ですかMemorystreamとaのFileStreamですか?



3
バイトの配列を受け取って、そのラッパーを作成し(Stream)、読み取り、書き込み、位置の変更などの便利なメソッドを公開します。これStreamで、特定のバッキングストアに基づいてその機能を継承および構築するバッキングストア(FileStream、MemoryStream)に基づいてクラスを作成できます。
マフィンマン

回答:


80

ストリームは、データを転送するために使用されるオブジェクトです。System.IO.Stream.NETの他のすべてのストリームクラスの派生元である汎用ストリームクラスがあります。Streamクラスは、バイトを扱います。

具象ストリームクラスは、バイト以外のタイプのデータを処理するために使用されます。例えば:

  • FileStreamクラスは、外部ソースがファイルの場合に使用されます
  • MemoryStream メモリにデータを保存するために使用されます
  • System.Net.Sockets.NetworkStream ネットワークデータを処理する

リーダ/ライタはのようなストリームStreamReaderStreamWriterストリームされていない-彼らは由来していませんSystem.IO.Stream、彼らは書き込みに役立つように設計してから、ストリームのデータを読んでいます!


3
したがって、私が正しく理解していれば、ストリームにはデータが含まれており、データを何も処理しません。リーダーとライターの「ヘルパー」クラスは、ストリーム内のデータを処理(操作)できますか?
Martijn、

9
いいえ、Streamはデータコンテナーではありません。データの転送に使用されています。たとえば、FileStreamはbyte []から物理ファイルにデータを転送し、NetworkStreamはソケットによってbyte []を転送します。リーダーライタークラスは、ストリームの書き込みと読み取りを行うヘルパークラスです。たとえば、StreamReaderを使用して、byte []ではなくStream文字列から読み取ることができます。FileStreamをパラメーターとして指定すると、NetworkStreamがソケットからであれば、FileStreamから読み取られます。
Arsen Mkrtchyan、

さらに、StreamReaderおよびStreamWriterは、TEXT(文字)ストリームの読み取りおよび書き込み用です。
1c1cle 2015

1
MemoryStreamの理解に役立つ優れた記事があります。codeproject.com/Articles/832387/...
Jiajiリー

2
@ user420667。良い質問。AudioStreamとTemperatureStreamのどちらの場合でも、デバイスに関連付けられているドライバーへのBinaryStreamsが最も可能性があります。または、インターフェイス専用に構築されたCustomStreamを作成することもできます。
1c1cle 2016

62

ここで他の答えを少し拡張し、点在する多くのサンプルコードの説明に役立てます。ほとんどの場合、直接ストリームを読み書きすることはありません。ストリームは、データを転送するための低レベルの手段です。

読み書き用の関数はすべてバイト指向であることがわかります(例:WriteByte())。整数、文字列などを処理するための関数はありません。これにより、ストリームは非常に汎用的なものになりますが、たとえば、テキストを転送するだけの場合は、操作が簡単ではなくなります。

ただし、.NETは、ネイティブタイプと低レベルストリームインターフェイスの間で変換し、ストリームとの間でデータを転送するクラスを提供します。注目すべきそのようなクラスは次のとおりです。

StreamWriter // Badly named. Should be TextWriter.
StreamReader // Badly named. Should be TextReader.
BinaryWriter
BinaryReader

これらを使用するには、最初にストリームを取得してから、上記のクラスの1つを作成し、それをストリームに関連付けます。例えば

MemoryStream memoryStream = new MemoryStream();
StreamWriter myStreamWriter = new StreamWriter(memoryStream);

StreamReaderとStreamWriterは、ネイティブ型とその文字列表現の間で変換を行い、文字列をストリームとの間でバイトとして転送します。そう

myStreamWriter.Write(123);

「123」(3つの文字「1」、「2」、「3」)をストリームに書き込みます。テキストファイル(htmlなど)を扱う場合、StreamReaderとStreamWriterが使用するクラスです。

一方

myBinaryWriter.Write(123);

32ビット整数値123(0x7B、0x00、0x00、0x00)を表す4バイトを書き込みます。バイナリファイルやネットワークプロトコルを扱っている場合は、BinaryReaderとBinaryWriterを使用できます。(ネットワークやその他のシステムとデータを交換する場合は、エンディアンに注意する必要がありますが、それは別の投稿です)。


StreamWriterとReaderのアダプタークラスは、深刻な名前が付けられています。言及していただきありがとうございます。彼らがどうしてこの名前を思いついたのかは、私にはまだ驚くべきことです。
Tarik

また、バイナリのライタークラスとリーダークラスの名前も不適切です。
Tarik 2019

22

ストリームは、大量のデータを処理するのに適しています。すべてのデータを同時にメモリにロードすることが実用的でない場合は、データをストリームとして開き、その小さなチャンクで作業できます。


1
あなたが今言ったことの例を見てみたいと思います。
Jenna Leaf 2016年

2
ストリームは少量のデータにも適しています。C#プログラマがファイルの内容を操作したい場合、データ量に関係なく、ストリームを使用する必要があります。同じことがネットワークストリームにも当てはまります。確かに、プログラマーがCのような低レベル言語でコーディングしている場合、文字またはバイトをディスクまたはソケットに直接書き込むことは可能ですが、少量のデータであっても、時間がかかり、エラー。
1c1cle 2016

10

ストリームはphysical、バイトストリームの単なる抽象化(またはラッパー)です。このphysicalストリームはと呼ばれますbase stream。したがって、ストリームラッパーが作成されるベースストリームは常に存在するため、ラッパーはベースストリームタイプに基づいて名前が付けられますFileStreamMemoryStreamなど

ストリームラッパーの利点は、基になるタイプのストリームなどとやり取りするための統合APIを取得できることですusb, file

データをストリームとして扱う理由 -データチャンクはオンデマンドで読み込まれるため、データ全体をメモリに読み込むのではなく、データをチャンクとして検査/処理できます。これは、OSイメージファイルの暗号化など、ほとんどのプログラムが大きなファイルを処理する方法です。


4

基本的なタイプは1つだけです Stream。ただし、さまざまな状況で、一部のメンバーは呼び出されたときに例外をスローします。これは、そのコンテキストでは操作が利用できないためです。

たとえば、a MemoryStreamはメモリのチャンクにバイトを移動する方法です。したがって、読み取りと書き込みを呼び出すことができます。

一方、aをFileStream使用すると、ファイルの読み取りまたは書き込み(またはその両方)を行うことができます。実際に読み取りまたは書き込みを実行できるかどうかは、ファイルを開いた方法によって異なります。読み取りアクセス用にファイルを開いただけでは、ファイルに書き込むことはできません。


3

私はMSDNのストリームを読むことから始めます: http //msdn.microsoft.com/en-us/library/system.io.stream.aspx

MemorystreamとFileStreamは、それぞれrawメモリとファイルを操作するために使用されるストリームです...


リンクをありがとう。「オンラインでソースコードを参照し、オフラインで表示するためのリファレンスをダウンロードして、デバッグ中にソース(パッチやアップデートを含む)をステップ実行できます」がとても気に入りました。この機能は、新しいレベルの洞察を提供します。
デビッド

1

私はそれらの異なる種類のストリームを呼び出さないでしょう。Streamクラスには、特定のストリームを読み書きできるかどうかを通知するCanReadプロパティとCanWriteプロパティがあります。

異なるストリームクラス(MemoryStreamとFileStreamなど)の主な違いは、バッキングストア(データの読み取り先または書き込み先)です。名前から明らかです。MemoryStreamはデータをメモリにのみ格納し、FileStreamはディスク上のファイルによってバックアップされ、NetworkStreamはネットワークからデータを読み取ります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.