はじめに
今回はMemoryStream
というメモリにデータを読み書きできるクラスの使い方について書きたいと思います。
使い方
MemoryStream
はStream
の派生クラスであり、バイトの読み取りと書き込みをサポートしています。
Stream クラス (System.IO) | Microsoft Docs
Stream
を利用する場合は3 つの基本的な操作を覚えればひとまずOKだと思います。
- 読み取り - ストリームからバイト配列などのデータ構造体にデータを転送します。
- 書き込み - データ ソースからストリームにデータを転送します。
- シーク - ストリーム内の現在位置を照会および変更します。
ファイルおよびストリーム入出力 - .NET | Microsoft Docs
MemoryStream
を利用するにあたって、サンプルコードとそれに対応する動きを記述した図を作りました。
private static void Main(string[] args) { UnicodeEncoding unicodeEncoding = new UnicodeEncoding(); byte[] text = unicodeEncoding.GetBytes("こんにちは"); // 10 : バイト配列の長さ Console.WriteLine(text.Length); // 100バイト分のCapacityを持つインスタンス作成 using (MemoryStream stream = new MemoryStream(100)) { // 0 : streamの現在のPosition Console.WriteLine(stream.Position); // 100 : ストリームに割り当てられたバイト数 Console.WriteLine(stream.Capacity); foreach (var writeByte in text) { // ストリームの現在Positionにバイトを書き込み、ストリームのPositionを1バイトだけ進める stream.WriteByte(writeByte); } // 10 Console.WriteLine(stream.Position); // ストリームの先頭から0バイトの位置にストリームのPositionを移動 // SeekOrigin.Bigin : ストリームの先頭を指定 // SeekOrigin.Current : ストリーム内の現在位置を指定 // SeekOrigin.End : ストリームの末尾を指定 stream.Seek(0, SeekOrigin.Begin); // 0 Console.WriteLine(stream.Position); var result = new byte[10]; for (var i = 0; i < result.Length; i++) { // バイトを読み取り、ストリームのPositionを1バイトだけ進める result[i] = (byte)stream.ReadByte(); } // 10 Console.WriteLine(stream.Position); // こんにちは Console.WriteLine(unicodeEncoding.GetString(result)); } }
またReadByte
やWriteByte
のように1バイトずつではなく、Read
やWrite
を利用することで複数バイトの読み書きを行えます。
private static void Main(string[] args) { UnicodeEncoding unicodeEncoding = new UnicodeEncoding(); byte[] text = unicodeEncoding.GetBytes("こんにちは"); // 100byte分のCapacityを持つインスタンス作成 using (MemoryStream stream = new MemoryStream(100)) { // textをストリームに書き込む // buffer : データの書き込み元となるバッファー // offset : buffer内のバイトオフセット // count : 書き込む最大バイト数 stream.Write(buffer: text, offset: 0, count: text.Length); // ストリームの先頭から0バイトの位置にストリームのPositionを移動 // SeekOrigin.Bigin : ストリームの先頭を指定 // SeekOrigin.Current : ストリーム内の現在位置を指定 // SeekOrigin.End : ストリームの末尾を指定 stream.Seek(0, SeekOrigin.Begin); var result = new byte[10]; // データをresultに書き込む // buffer : 読み取られた文字を書き込むバイト配列 // offset : buffer内のバイトオフセット // count : 読み取る最大バイト数 stream.Read(buffer: result, offset: 0, count: result.Length); // こんにちは Console.WriteLine(unicodeEncoding.GetString(result)); } }
public override int Read (byte[] buffer, int offset, int count); public override void Write (byte[] buffer, int offset, int count);
オーバーロードはいくつかあるので詳細は公式ドキュメントを見てみてください。