
지난번에는 StreamWriter와 StreamReader를 이용해
텍스트를 파일에 자유롭게 쓰고 읽는 법을 배웠습니다.
로그나 간단한 메모를 저장하는 용도면 충분하지만
데이터 묶음(객체)을 매번 한 줄 한 줄 저장하는 건 번거롭습니다.
이 문제를 해결해 주는 기술이 객체 직렬화(Object Serialization)입니다.
직렬화(Serialization)는 객체 또는 데이터 구조를 파일에 저장하거나 전송할 수 있도록,
텍스트나 바이트 스트림 형태로 데이터를 변환하는 과정을 말합니다.
반대 과정은 역직렬화(Deserialization)로, 다시 원래의 객체로 복원합니다.
비유해서 쉽게 설명해 볼까요? 우리가 만든 멋진 레고 작품(객체)을
친구에게 보내고 싶다고 상상해 봅시다. 작품을 통째로 보낼 순 없으니,
우리는 작품을 분해해서 부품 목록과 조립 설명서(직렬화된 데이터)를 만들어 보냅니다.
친구는 그 설명서를 보고 다시 똑같은 레고 작품(객체)을 조립할 수 있죠.
직렬화/역직렬화 분야에서 JSON(JavaScript Object Notation)이 대세입니다.
가볍고, 사람이 읽고 쓰기 쉬우며, 대부분의 프로그래밍 언어에서 지원하기 때문이죠.
우리는 C#에 내장된 System.Text.Json을 사용해 볼 겁니다.
먼저, Player객체를 생성하고, JSON 문자열로 변환한 뒤 파일에 저장해 보겠습니다.
[코드]
using System;
using System.IO;
using System.Text.Json;
// 직렬화를 위한 데이터 모델(클래스)
public class Player
{
public string Name { get; set; }
public int Level { get; set; }
public int Hp { get; set; }
public bool isLoggedIn { get; set; }
}
class Program
{
static void Main()
{
// 1. 저장할 객체 생성
Player myPlayer = new Player
{
Name = "홍길동",
Level = 10,
Hp = 100,
isLoggedIn = true
};
// 2. 객체를 JSON 문자열로 직렬화
// JsonSerializerOptions를 사용하여 보기 좋게 들여쓰기(Indented)합니다.
var options = new JsonSerializerOptions { WriteIndented = true };
string jsonString = JsonSerializer.Serialize(myPlayer, options);
Console.WriteLine("--- 직렬화된 JSON 문자열 ---");
Console.WriteLine(jsonString);
// 3. JSON 문자열을 파일에 저장
Directory.CreateDirectory(@"C:\Temp");
string filePath = @"C:\Temp\player.json";
File.WriteAllText(filePath, jsonString);
Console.WriteLine($"\n{filePath} 파일 저장!");
}
}
JsonSerializer.Serialize(객체): 객체를 JSON 문자열로 변환합니다.JsonSerializerOptions { WriteIndented = true }:이번에는 파일에 저장된 JSON을 다시 읽어와서 Player객체로 복원해 보겠습니다.
[코드]
// 위에서 만든 파일을 읽어봅시다.
if (File.Exists(filePath))
{
// 1. 파일에서 JSON 문자열 읽기
string jsonFromFile = File.ReadAllText(filePath);
// 2. JSON 문자열을 Player 객체로 역직렬화
Player restoredPlayer = JsonSerializer.Deserialize<Player>(jsonFromFile);
// 3. 복원된 객체의 속성 확인
if (restoredPlayer != null)
{
Console.WriteLine("\n--- 역직렬화로 복원된 객체 정보 ---");
Console.WriteLine($"이름: {restoredPlayer.Name}");
Console.WriteLine($"레벨: {restoredPlayer.Level}");
Console.WriteLine($"HP: {restoredPlayer.Hp}");
Console.WriteLine($"로그인 상태: {restoredPlayer.isLoggedIn}");
}
}
JsonSerializer.Deserialize<T>(문자열): JSON 문자열을T)의 객체로 복원할지 제네릭<T>으로 알려주는 것이 핵심입니다.Player객체로 만들 것이므로 <Player>를 사용했습니다.[실행 결과]
--- 직렬화된 JSON 문자열 ---
{
"Name": "\uC6A9\uC0AC",
"Level": 10,
"Hp": 100,
"isLoggedIn": true
}
C:\Temp\player.json 파일 저장!
--- 역직렬화로 복원된 객체 정보 ---
이름: 홍길동
레벨: 10
HP: 100
로그인 상태: True
JsonSerializer는 놀랍게도 객체의 묶음(컬렉션, 리스트)도 알아서 처리해 줍니다!
[코드]
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
public class Player
{
public string Name { get; set; }
public int Level { get; set; }
public int Hp { get; set; }
public bool isLoggedIn { get; set; }
}
class Program
{
static void Main()
{
// 1. 저장할 객체 '리스트' 생성
var playerParty = new List<Player>
{
new Player { Name = "홍길동", Level = 10, Hp = 100, isLoggedIn = true },
new Player { Name = "이순신", Level = 12, Hp = 75, isLoggedIn = true },
new Player { Name = "을지문덕", Level = 9, Hp = 85, isLoggedIn = false }
};
// 2. 객체 '리스트'를 JSON 문자열로 직렬화
// 단일 객체를 다룰 때와 코드가 완전히 동일합니다!
var options = new JsonSerializerOptions { WriteIndented = true };
string jsonString = JsonSerializer.Serialize(playerParty, options);
Console.WriteLine("--- 직렬화된 JSON 문자열 (배열) ---");
Console.WriteLine(jsonString);
// 3. JSON 문자열을 파일에 저장
Directory.CreateDirectory(@"C:\Temp");
string filePath = @"C:\Temp\party.json";
File.WriteAllText(filePath, jsonString);
Console.WriteLine($"\n{filePath} 에 파티 정보 저장 완료!");
if (File.Exists(filePath))
{
// 4. 파일에서 JSON 문자열 읽기
string jsonFromFile = File.ReadAllText(filePath);
// 5. JSON 문자열을 'List<Player>' 객체로 역직렬화
// 여기가 가장 중요합니다! 어떤 타입으로 복원할지 정확히 알려줘야 합니다.
List<Player> restoredParty =
JsonSerializer.Deserialize<List<Player>>(jsonFromFile);
// 6. 복원된 리스트의 내용 확인
if (restoredParty != null)
{
Console.WriteLine("\n--- 역직렬화로 복원된 파티 정보 ---");
foreach (var player in restoredParty)
{
Console.WriteLine($"이름: {player.Name}, 접속: {player.isLoggedIn}");
}
}
}
}
}
[실행 결과]
--- 직렬화된 JSON 문자열 (배열) ---
[
{
"Name": "\uD64D\uAE38\uB3D9",
"Level": 10,
"Hp": 100,
"isLoggedIn": true
},
{
"Name": "\uC774\uC21C\uC2E0",
"Level": 12,
"Hp": 75,
"isLoggedIn": true
},
{
"Name": "\uC744\uC9C0\uBB38\uB355",
"Level": 9,
"Hp": 85,
"isLoggedIn": false
}
]
C:\Temp\party.json 에 파티 정보 저장 완료!
--- 역직렬화로 복원된 파티 정보 ---
이름: 홍길동, 접속: True
이름: 이순신, 접속: True
이름: 을지문덕, 접속: False
객체를 파일에 저장하고 불러오는 강력한 기술, 직렬화에 대해 알아봤습니다.
System.Text.Json라이브러리 덕분에 이 모든 것이 가능했죠.
| 용어 | 역할 | 핵심 메서드 |
|---|---|---|
| 직렬화(Serialization) | 객체 ⮕ JSON 문자열 (설명서 만들기) | JsonSerializer.Serialize() |
| 역직렬화(Deserialization) | JSON 문자열 ⮕ 객체 (설명서 보고 조립하기) | JsonSerializer.Deserialize<T>() |