
JSON 형식은 설정 파일이나 데이터 교환용으로는 정말 훌륭한 방식이죠.
하지만 모든 데이터가 텍스트일까요? 이미지, 사운드, 혹은 게임 세이브 파일처럼
데이터의 크기를 줄이고 처리 속도를 높이는 게 더 중요할 때는 어떻게 해야 할까요?
이럴 때 우리는 컴퓨터의 모국어, 바이너리(Binary) 데이터와 직접 대화해야 합니다.
JSON이나 XML 같은 텍스트 기반 데이터는 사람이 읽기 쉽다는 장점이 있지만,
숫자 10을 표현하기 위해 "Level": 10이라는 여러 개의 문자를 사용하죠.
바이너리 저장은 이런 부가 정보 없이 컴퓨터가 이해하는 방식으로 곧바로 저장합니다.
비유하자면...
- 텍스트(JSON): 재료 목록과 조리법이 상세히 적힌 '레시피 북'
(누구나 읽고 이해할 수 있지만, 정보량이 많음)- 바이너리(Binary): 요리에 필요한 재료만 담아놓은 '밀키트'
(바로 요리(처리)하기에 최적화되어 있고 군더더기가 없음)
| 구분 | 장점 | 단점 |
|---|---|---|
| 텍스트(JSON) | 사람이 읽고 수정하기 쉬움, 유연함 | 데이터 크기가 큼, 파싱(해석) 과정 필요 |
| 바이너리 | 데이터 크기가 작음, 읽고 쓰는 속도가 빠름 | 사람이 읽을 수 없음, 정해진 규격대로만 읽어야 함 |
BinaryWriter는 FileStream과 같은 기본 스트림 위에 덧씌워 사용하는 보조 스트림입니다.
C#의 자료형을 바이너리 형태로 변환하여 스트림에 써주는 역할을 합니다.
[코드]
using System;
using System.IO;
string filePath = @"C:\Temp\game.sav";
Directory.CreateDirectory(@"C:\Temp");
try
{
// 1. 기반이 될 FileStream을 생성합니다.
using (FileStream fs = new FileStream(filePath, FileMode.Create))
// 2. FileStream 위에 BinaryWriter를 덧씌웁니다.
using (BinaryWriter bw = new BinaryWriter(fs))
{
// 3. 다양한 타입의 데이터를 순서대로 씁니다.
bw.Write("홍길동"); // string
bw.Write(15); // int
bw.Write(150.5); // double
bw.Write(true); // bool
Console.WriteLine("바이너리 파일 쓰기 완료!");
}
}
catch (Exception ex)
{
Console.WriteLine($"오류 발생: {ex.Message}");
}
bw.Write()메서드는 타입에 맞춰 바이너리 데이터를 자동으로 변환해 줍니다.BinaryReader는 바이너리 데이터를 다시 C# 자료형에 맞게 복원하는 역할을 합니다.
만약 string, int, double순서로 썼다면, 데이터의 순서에 맞게
ReadString(), ReadInt32(), ReadDouble()순서로 읽어야 합니다.
순서나 타입이 하나라도 틀리면 데이터를 잘못 읽게 되거나 프로그램에서 오류가 발생합니다.
[코드]
if (File.Exists(filePath))
{
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
using (BinaryReader br = new BinaryReader(fs))
{
// 쓴 순서와 타입 그대로 읽어옵니다.
string name = br.ReadString();
int level = br.ReadInt32(); // int는 32비트 정수
double hp = br.ReadDouble();
bool isAlive = br.ReadBoolean();
Console.WriteLine("\n--- 바이너리 파일에서 읽은 내용 ---");
Console.WriteLine($"이름: {name}");
Console.WriteLine($"레벨: {level}");
Console.WriteLine($"HP: {hp}");
Console.WriteLine($"생존 여부: {isAlive}");
}
}
catch (Exception ex)
{
Console.WriteLine($"오류 발생: {ex.Message}");
}
}
[실행 결과]
바이너리 파일 쓰기 완료!
--- 바이너리 파일에서 읽은 내용 ---
이름: 홍길동
레벨: 15
HP: 150.5
생존 여부: True
바이너리 데이터는 사람이 직접 읽을 필요가 없는 데이터일 때 적합하게 사용됩니다.
| 클래스 | 특징 | 비유 |
|---|---|---|
BinaryWriter | 자료형을 바이너리 데이터로 변환 | 데이터를 0과 1로 압축 |
BinaryReader | 바이너리 데이터를 자료형으로 변환 | 0과 1을 데이터로 해석 |