.NET Frameworkで実行されるすべての入出力作業は、ストリームを使用する必要があります。ストリームは、シリアルデバイスの抽象的な表現です。シリアル化デバイスは、データを線形に格納でき、同じ方法でアクセスできます。一度に1バイトです。
ストリームには次の2つのタイプがあります。
- 出力ストリーム:外部ターゲットにデータを書き込む場合、出力ストリームを使用する必要があります。これは、物理ディスクファイル、ネットワークの場所、プリンター、または別のプログラムである可能性があります。
- 入力ストリーム:プログラムがアクセスできるメモリまたは変数にデータを読み込むために使用されます。これまで、私たちが使用した入力ストリームの最も一般的な形式はキーボードです。
ストリームの関連するインターフェイスとクラスは主にSystem.IO
名前空間にあり、Stream
クラスは抽象クラスであり、さまざまなアクセスオブジェクトに対して3つの重要なサブクラスがあります。FileStream
クラスはファイル操作をMemoryStream
表し、BufferedStream
クラスはバッファ処理を表します。
1.ストリームクラス
Stream
次の表に示すように、抽象クラスには、ストリームに必要な多くの属性とメソッドが含まれています。
これらの属性とメソッドには、ストリームの読み取りと書き込みのすべての側面が含まれます。読み取りおよび書き込み操作の4つの方法は次のとおりです。
int ReadByte();
int Read(byte[] array, int offset, int count);
void WriteByte(byte value);
void Write(byte[] array, int offset, int count);
その中ReadByte()
で、読み込まれたバイトは整数に変換されて返されます。読み込まれたバイトがない場合は、を返し-1
ます。Read()
このメソッドは、読み取られたバイト数を返します。、など
によりBeginRead()
、Streamクラスは非同期I / O操作をサポートできます。メソッドとは、ストリーム内の検索ポインタを見つけて、次の読み取りまたは書き込み操作の位置を決定することを意味します。このようなストリームでは、その属性値はであり、そのメソッドを使用してポインターの位置を設定できます。この方法には2つのパラメーターが必要です。1つは検索ポインターの動きの値を示すために使用され、もう1つはポインターの動きの参照位置を決定するために使用されます。参照位置は列挙メンバーであり、次の3つの状況のいずれかになります。EndRead()
BeginWrite()
EndWrie()
Seek()
CanSeek
true
Seek()
Seek()
SeekOrigin
- ①
SeekOrigin.Begin
(ファイルの先頭); - ②
SeekOrigin.Current
(ファイル内のポインタの現在位置); - ③
SeekOrigin.End
(ファイルの終わり)。
次のコードは、ファイルを検索する方法を示しています。
aStream.Seek(200, SeekOrigin.Begin); // 从开头移到200位置
aStream.Seek(0, SeekOrigin.End); // 移到文件尾
aStream.Seek(-20, SeekOrigin.Current); // 从当前位置反向移动20
2.FileStreamクラス
FileStream
それはそれStream
から直接派生しています。FileStream
オブジェクトは、ファイルからコンテンツを読み取ったり、ファイルにコンテンツを書き込んだりでき、バイト、文字、文字列、およびその他のデータ型を処理できます。このオブジェクトは、標準の入出力および標準のエラー出力を実行するためにも使用できます。そのアプリケーションは最下層に近いため
、FileStream
オブジェクトは通常、単独では使用されないことに注意してください。このオブジェクトはバイトの読み取りと書き込みしかできないため、このオブジェクトを使用するときは、文字列、数値、およびオブジェクトをバイトに変換してから渡す必要がFileStream
あります。これを考慮して、FileStream
通常、BinaryWriter
またはなどの他のクラスにパッケージ化されて使用されますTextReader
。これらのクラスは、高レベルのデータ構造を処理できます。FileStreamクラスにはさまざまな形式の構築メソッドがあるため、次のパラメーターのさまざまな組み合わせに応じて、さまざまな構築メソッドを使用できますFileStream
。
- ①ファイル名;
- ②ファイルハンドル-ファイルハンドルを表すために使用される整数。
- ③アクセスモード-FileMode列挙値の1つ。
- ④読み取り/書き込み権限-FileAccess列挙値の1つ。
- ⑤共有モード-FileShare列挙値の1つ。
- ⑥バッファサイズ。
表6-3、表6-4、および表6-5に、それぞれファイルアクセスモード、アクセス許可、および共有モードを示します。
たとえば、ファイルを作成し、そのファイルで共有読み取り操作をサポートするには、次のようにします。
FileStream fs = new FileStream(@"c:\temp\foo.txt", FileMode.Create, FileAccess.Reead);
FIleStream
Stream
継承されたプロパティの追加とは別に、同時に作成する同期または非同期の方法にすることができますが、プロパティを増やすこともできIsAsync
ます。さらに、次の表にリストされているメソッドがこのクラスに追加されます。この
GetHandle()
メソッドは、ネイティブオペレーティングシステム関数(Win32などReadFile()
)で使用できる識別子を返すことができますが、このメソッドの使用には注意が必要です。ファイルハンドルを使用して基になるファイルに変更を加えてからファイルを使用しようとすると、ファイル内FileStream
のデータが損傷する可能性があります。
FileStream
クラスの操作中に、次の例外が生成される場合があります。
- ①ArgumentException-パスがヌル文字です
- ②ArgumentNullException-パスはnull参照です
- ③SecurityException-ファイルに操作権限がありません
- ④FileNotFoundException-ファイルが見つかりません
- ⑤IOException-間違ったドライバを指定するなど、その他のI / Oエラーが発生しました
- ⑥DirectoryNotFoundException-ディレクトリが存在しません
たとえばFileStream
、ファイルの内容を読み書きするには、次のようにします。
using System;
using System.IO;
class Test
{
static void Main(){
try {
FileStream fsw = new FileStream("test.dat", FileMode.Create, FileAccess.Write);
// Wirte some data to the stream
fsw.WriteByte(33);
fsw.Write(new byte[] {
34, 35, 36 }, 0, 3);
fsw.Close();
FileStream fsr = new FileStream("test.dat", FileMode.Open, FileAccess.Read);
Console.WriteLine(fsr.ReadByte());
Console.WriteLine(fsr.ReadByte());
Console.WriteLine(fsr.ReadByte());
Console.WriteLine(fsr.ReadByte());
} catch (Exception e) {
Console.WriteLine("Exception:" + e.ToString());
}
}
}
演算結果:
3.MemoryStreamクラス
MemoryStream
Stream
継承されたクラスからも、ファイルの代わりにメモリを使用してストリームを直接格納しますが、処理はFileStream
非常に似ています。MemoryStream
データはバイト配列の形式でメモリに保存され、アプリケーションの一時ファイルの役割を置き換えるために使用できます。
同様にFileStream
同じ、MemoryStream
多くの施工方法があります。次の2つがより一般的に使用されます。
MemoryStream();
MemoryStream(byte []);
ここで最初の構築方法を使用しMemoryStream
て、データがストリームの最後に書き込まれるときに、それにMemoryStream
応じて拡張できることを確認します。2番目の構築メソッドは、指定されたバイト配列に基づいてMemoryStream
クラスの新しいインスタンスを作成するため、作成されたストリームのサイズを変更することはできません。継承されたプロパティに
加えてStream
、追加のプロパティMemoryStream
が追加されましたCapacity
。Capacity
この属性は、ストリームに現在割り当てられているバイト数を示すために使用できます。この属性は、バイト配列ベースのストリームを使用する場合に非常に役立ちます。これは、この属性が配列のサイズをLength
示し、属性が現在使用されているバイト数を示すことができるためです。
MemoryStream
この機能はメモリI / Oに必要ないため、非同期の読み取り/書き込みメソッドを実行することはできません。ただし、オブジェクトは次の3つの追加メソッドを実行できます。
- ①-
GetBuffer()
ストリーム内のバイト配列への参照を返します - ②-
ToArray()
すべての内容をバイト配列に書き込む - ③-
WriteTo()
ストリームの内容を別のストリームに書き込む
たとえば、MemoryStreamを使用してメモリを操作します。
using System;
using System.IO;
class Test
{
static void Main(){
try {
byte[] ary = {
33, 34, 35, 36, 37 };
int b;
MemoryStream msr = new MemoryStream(ary);
MemoryStream msw = new MemoryStream();
while ((b = msr.ReadByte()) != -1) {
msw.WriteByte((byte)(b + 3));
}
byte[] result = msw.ToArray();
foreach (byte bt in result)
Console.WriteLine(bt);
} catch (Exception e) {
Console.WriteLine("Exception:" + e.ToString());
}
}
}
演算結果:
4.BufferedStreaクラス
BufferedStream
このクラスはデータをメモリにキャッシュできるため、読み取りおよび書き込み操作の実行効率を向上させることができ、それによってオペレーティングシステムへの呼び出し回数を減らすことができます。BufferedStream
単独で使用することはできませんが、他のタイプのストリーム、特に以下で説明するタイプBinaryWriter
とBinaryReader
タイプにパッケージ化する必要があります。さらに、ネットワークストリーム(NetworkStream)をキャッシュしてラップすることも一般的です。以下のためにBinaryStream
呼び出しFlush()
操作、キャッシュされたコンテンツは、ストリームに書き込むことができます。