본문 바로가기
C#/Stream

BinaryWriter/Reader 이해하기: Write, Read, vs StreamWriter

by PlaneK 2021. 7. 12.

Write, Read

BinaryWriterBinaryReader는 스트림 버퍼를 쓰거나 읽는 클래스다.

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에 저장한다.

📖 더 알아보기
BinaryWriterFlush()함수는 재정의 되지 않은 빈 함수이다. 
따라서 Flush()함수를 호출해봤자 아무 일도 일어나지 않는다. "Do Nothing"

C# 레퍼런스

버퍼 저장 방식

BinaryWriter는 버퍼의 헤더(Prefix)에 길이를 붙인다는 점을 유의해야한다.

스트림 쓰기를 BinaryWriter로 했다가

스트림 읽기를 StreamReader로 하면

데이터가 어긋날 수 있다.

 

'C# > Stream' 카테고리의 다른 글

StreamWriter/Reader 이해하기: WriteLine, Flush  (0) 2021.07.09

댓글