Programming/.NET

MemoryStream은 일련의 바이트 데이터를 메모리에 쓰고 읽는 기능을 제공합니다.

 

byte[] cb = BitConverter.GetBytes('a');
byte[] ib = BitConverter.GetBytes(1000);

MemoryStream ms = new MemoryStream();

 

ms.Write(cb, 0, cb.Length);
ms.Write(ib, 0, ib.Length);

 

예제에서는 문자형 a와 정수형 1000데이터를 바이트로 변환해 MemoryStream으로 메모리에 쓰고 있습니다. 메모리에 쓸때는 Write메서드를 사용하며 0부터 각 데이터 배열길이까지 전체를 쓰도록 하고 있습니다.

 

byte[] cb = BitConverter.GetBytes('a');
byte[] ib = BitConverter.GetBytes(1000);

MemoryStream ms = new MemoryStream();

 

ms.Write(cb, 0, cb.Length);
ms.Write(ib, 0, ib.Length);

ms.Position = 0;

byte[] outcb = new byte[2];
byte[] outib = new byte[4];

ms.Read(outcb, 0, 2);
ms.Read(outib, 0, 4);

char c = BitConverter.ToChar(outcb, 0);
int i = BitConverter.ToInt32(outib, 0);

Console.WriteLine(c);
Console.WriteLine(i);

 

메모리에 데이터를 쓴뒤 읽기 위해서는 Position 속성을 0으로 하여 MemoryStream의 내부 배열위치를 초기화해야 합니다. 그래야 다시 처음부터 데이터를 읽을 수 있습니다. 읽기 메서드는 Read이며 이때 데이터를 읽어들이기 위한 byte배열이 별도로 필요합니다.

 

byte[] cb = BitConverter.GetBytes('a');
byte[] ib = BitConverter.GetBytes(1000);

MemoryStream ms = new MemoryStream();

 

ms.Write(cb, 0, cb.Length);
ms.Write(ib, 0, ib.Length);

ms.Position = 0;

byte[] outData = ms.ToArray();

char c = BitConverter.ToChar(outData, 0);
int i = BitConverter.ToInt32(outData, 2);

Console.WriteLine(c);
Console.WriteLine(i);

 

위 예제는 MemoryStream의 ToArray() 메서드를 통해 byte배열 전체를 가져오도록한 것입니다. 이렇게 전체를 가져오고 나면 해당 byte배열에 원하는 데이터를 가져올때 가져올 데이터의 시작위치를 지정하는것에 주의(int i = BitConverter.ToInt32(outData, 2))하도록 합니다.

 

같은 방법으로 문자열을 MemoryStream에 담을 수도 있습니다.

 

MemoryStream ms = new MemoryStream();

byte[] b = Encoding.UTF8.GetBytes("Hello World!");
ms.Write(b, 0, b.Length);

 

문자열은 인코딩을 통해서 byte배열에 담는데 이걸 좀더 간단히 하기위해 StreamWriter를 사용할 수 있습니다.

 

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms, Encoding.UTF8);

sw.WriteLine("hello world!");
sw.Flush();

 

StreamWriter의 WriteLine메서드는 문자열쓰기 전용이며 정수형등 다른 단일 데이터의 경우 Write메서드를 사용합니다.

 

StreamWriter가 데이터를 쓸때는 곧장 MemoryStream에 기록하는 것이 아니라 내부적으로 갖고 있는 일정한 크기의 byte배열버퍼에 데이터를 기록합니다. 그러다 만약 일정한 크기에 도달하면 그때 MemoryStream에 기록하게 되는데 마지막에 있는 Flush() 메서드는 쓸데이터가 버퍼에 다 차지않더라도 MemoryStream에 접근해 데이터를 기록하도록 하는 메서드입니다.

 

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms, Encoding.UTF8);

sw.WriteLine("hello world!");
sw.Flush();

ms.Position = 0;

StreamReader sr = new StreamReader(ms, Encoding.UTF8);
string s = sr.ReadToEnd();

Console.WriteLine(s);

 

StreamWriter로 쓴 데이터는 다시 StreamReader로 읽을 수 있습니다. 인코딩방식은 StreamWriter를 사용할때와 똑같이 지정해야 하며 데이터를 반드시 Position을 0으로 맞춰야 합니다.

 

MemoryStream ms = new MemoryStream();

BinaryWriter bw = new BinaryWriter(ms);
bw.Write("hello ");
bw.Write("world!" + Environment.NewLine);
bw.Flush();

 

BinaryWriter는 메모리에 2진데이터를 쓰기위한 전용입니다. BinaryWriter를 통해 데이터를 쓰는 경우 byte배열 중간중간에 다음 몇바이트가 데이터바이트인지를 나타내는 구분자가 추가됩니다. 때문에 뭔가 규격화된 데이터를 다루고자할때는 BinaryWriter를 사용합니다. 쓰기 작업에 대한 효휼성도 좋아서 성능이 우선시 되는 상황이라면 BinaryWriter도 좋은 선택이 될 수 있습니다.

 

MemoryStream ms = new MemoryStream();

BinaryWriter bw = new BinaryWriter(ms);
bw.Write("hello ");
bw.Write("world!" + Environment.NewLine);
bw.Flush();

ms.Position = 0;

BinaryReader br = new BinaryReader(ms);
string s = br.ReadString();
s += br.ReadString();

Console.WriteLine(s);

 

BinaryWriter로 작성된 데이터는 BinaryReader로 읽을 수 있습니다. 예제에서는 ReadString() 메서드를 2번 호출해 문자열데이터를 읽고 있는데 ReadString()메서드를 한번 호출할때마다 BinaryWriter를 사용할때 Write메서드로 작성한 데이터를 한묶음씩 읽어오기 때문입니다.

0 0