Write, Read
BinaryWriter와 BinaryReader는 스트림 버퍼를 쓰거나 읽는 클래스다.
FileStream을 Write/Read 해보자.
using System;
using System.IO;
namespace StreamStudy
{
class Program
{
static void Main(string[] args)
{
DirectoryInfo[] cDirs = new DirectoryInfo(@"c:\").GetDirectories();
if (File.Exists("CDriveDirs.txt"))
{
File.Delete("CDriveDirs.txt");
}
// Write
using FileStream fw = new FileStream("CDriveDirs.txt", FileMode.Create, FileAccess.Write);
using (BinaryWriter bw = new BinaryWriter(fw))
{
foreach (DirectoryInfo dir in cDirs)
{
bw.Write(dir.Name);
}
}
// Read
using FileStream fr = new FileStream("CDriveDirs.txt", FileMode.Open, FileAccess.Read);
using BinaryReader br = new BinaryReader(fr);
// Stream을 읽을 때마다 Position이 증가한다.
// Position == Length 의 의미는 스트림을 모두 읽었다는 뜻.
while (br.BaseStream.Position != br.BaseStream.Length)
{
// 버퍼에서 읽어들인 부분은 비워지고 남은 값이 채워진다. = Flush
Console.WriteLine(br.ReadString());
}
}
}
}
샘플코드는 위와 같다.
위 디렉토리 리스트를 .txt 파일(FileStream)으로 담아본다.
샘플코드의 결과는 위와 같다.
BinaryWriter는 버퍼에 해당 문자열을 입력하는데, 문자열의 길이를 먼저 입력한다.
"Logs"는 길이가 4이므로 버퍼에 { 4, 76, 111, 103, 115, 0, 0, ... } 이 저장된다.
마찬가지로 "DPP"는 길이가 3이므로 버퍼에 { 3, 68, 80, 80, 0, 0, ...} 이 저장된다.
✏️ 유니코드
바이너리 값 4와 3의 유니코드는 각각 ''와 ''를 나타낸다.
https://unicode-table.com/kr/0003/
BinaryReader.ReadString()함수는 버퍼의 첫 번째 값을 길이로 참조하여
해당 길이만큼 문자열을 뽑아낸다.
✏️ BaseStream.Position
이 속성은 BinaryReader가 인덱스로 사용한다. BinaryReader.ReadString() 함수가 한번 호출 될 때 마다 BaseStream.Position이 현재 읽은 문자열 갯수만큼 카운트 된다.
읽어야할 문자 갯수는 버퍼에 기록되있어서 그 값을 참조하여 끊어 읽는다.
vs StreamWriter
Flush()
StreamWriter는 데이터를 임시로 자신의 _charBuffer에 저장해두었다가,
Flush() 될 때 BaseStream으로 옮겨담았지만,
BinaryWriter는 Flush()하지 않아도 곧바로 BaseStream에 저장한다.
📖 더 알아보기
BinaryWriter의 Flush()함수는 재정의 되지 않은 빈 함수이다.
따라서 Flush()함수를 호출해봤자 아무 일도 일어나지 않는다. "Do Nothing"
버퍼 저장 방식
BinaryWriter는 버퍼의 헤더(Prefix)에 길이를 붙인다는 점을 유의해야한다.
스트림 쓰기를 BinaryWriter로 했다가
스트림 읽기를 StreamReader로 하면
데이터가 어긋날 수 있다.
'C# > Stream' 카테고리의 다른 글
StreamWriter/Reader 이해하기: WriteLine, Flush (0) | 2021.07.09 |
---|
댓글