12. 직렬화 및 리플렉션
직렬화란 프로세스의 개체 정보를 선형적(연속적인 선의 형태)으로 다른 매체에 기록 혹은 전송하는 것을 말합니다. 그리고 다른 매체의 정보를 읽어나 수신하여 프로세스의 개체를 만드는 것을 역직렬화라 부릅니다. 이번 장에서는 C#에서 제공하는 직렬화와 역직렬화를 사용하여 파일 입출력하는 예를 살펴볼게요.
그리고 리플렉션은 형식 정보를 이용하여 개체를 생성하거나 메서드 등을 사용하는 것을 말합니다. 특히 프로그램 동작 중에 명시적으로 라이브러리를 로딩하여 사용할 때 리플렉션을 사용합니다.
12.1 직렬화
C#에서는 ISerializable 어튜리뷰트를 제공하고 있으며 이를 사용하면 별다른 작업없이 직렬화할 수 있습니다. 직렬화하려면 어느 개체 정보를 직렬화할 것인지 어느 매체에 직렬화할 것인지 결정합니다. 그리고 C#에서는 직렬화할 때 어떠한 포멧으로 직렬화할 것인지에 따라 포멧터를 이용하여 직렬화를 수행합니다.
먼저 특정 형식의 개체를 직렬화하려면 해당 개체는 직렬화 가능한 대상이어야 합니다. 특정 형식의 개체를 직렬화할 수 있게 정의하려면 ISerializable 어튜리뷰트를 지정합니다.
[Serializable]
class Man
{
internal string Name
{
get;
private set;
}
internal int Age
{
get;
private set;
}
internal Man(string name, int age)
{
Name = name;
Age = age;
}
public override string ToString()
{
return string.Format("이름:{0} 나이:{1}", Name, Age);
}
}
그리고 직렬화를 할 때는 포멧터를 사용합니다. C#에서 제공하는 포멧터에는 바이너리 포멧터와 Soap 포멧터 등이 있습니다. 바이너리 포멧터는 개체의 정보를 그대로 직렬화하고 Soap 포멧터는 개체의 정보를 xml 형태의 태그로 메터 데이터와 함께 값을 표현하고 이러한 정보를 Soap으로 감싸(Envelop) 직렬화합니다.
직렬화할 때는 포멧터의 Serialize 메서드에 직렬화 대상 매체와 대상 개체를 전달합니다.
Man man = new Man("홍길동", 29); //직렬화 대상 개체
FileStream fs = new FileStream("man.txt",FileMode.Create); //직렬화 대상 매체
BinaryFormatter bf = new BinaryFormatter(); //포멧터
bf.Serialize(fs, man); //직렬화 수행
fs.Close();
그리고 역직렬화는 포멧터의 DeSerialize 메서드에 대상 매체를 전달하면 역직렬화하여 개체를 반환합니다. 반환 형식은 object이며 실제 직렬화했던 대상 개체 형식으로 변환하여 사용합니다.
FileStream fs2 = new FileStream("man.txt", FileMode.Open);//대상 매체
BinaryFormatter bf2 = new BinaryFormatter(); //포멧터
Man man2 = bf2.Deserialize(fs2) as Man; //역직렬화
fs2.Close();
다음은 Binary 포멧터로 직렬화와 역직렬화를 제대로 수행하는지 확인하는 예제 코드입니다.
static void Main(string[] args)
{
Man man = new Man("홍길동", 29); //직렬화 대상 개체
FileStream fs = new FileStream("man.txt",FileMode.Create); //직렬화 대상 매체
BinaryFormatter bf = new BinaryFormatter(); //포멧터
bf.Serialize(fs, man); //직렬화 수행
fs.Close();
FileStream fs2 = new FileStream("man.txt", FileMode.Open);//대상 매체
BinaryFormatter bf2 = new BinaryFormatter(); //포멧터
Man man2 = bf2.Deserialize(fs2) as Man; //역직렬화
fs2.Close();
Console.WriteLine(man2);
}
▶ 실행 결과
이름:홍길동 나이:29 |
프로젝트의 출력 폴더를 확인하면 man.txt 파일이 생긴 것을 알 수 있고 개체의 정보가 쓰여져 있음을 확인할 수 있습니다.
Soap 포멧터로 직렬화 및 역직렬화하는 것도 바이너리 포멧터로 하는 것과 같습니다. Soap 포멧터를 사용하려면 System.Runtime.Serialization.Formatters.Soap 어셈블리를 참조 추가해야 합니다.
[그림 12.1] Soap 포멧터 사용을 위해 어셈블리 참조 추가
Soap 포멧터를 사용하여 직렬화 및 역직렬화 예제 코드입니다.
static void Main(string[] args)
{
Man man = new Man("홍길동", 29); //직렬화 대상 개체
FileStream fs = new FileStream("man.xml", FileMode.Create); //직렬화 대상 매체
SoapFormatter sf = new SoapFormatter(); //포멧터
sf.Serialize(fs, man); //직렬화 수행
fs.Close();
FileStream fs2 = new FileStream("man.xml", FileMode.Open);//대상 매체
SoapFormatter sf2 = new SoapFormatter(); //포멧터
Man man2 = sf2.Deserialize(fs2) as Man; //역직렬화
fs2.Close();
Console.WriteLine(man2);
}
출력 폴더에 만들어진 파일을 열어 보면 바이너리 포멧터를 사용할 때와 내용이 다름을 알 수 있습니다. 파일에 쓰여진 바이트 수를 확인해 보면 Soap 포멧터로 만들어진 파일이 큰 것을 알 수 있습니다.
관련 게시물
[C#] 12. 직렬화와 리플렉션 - 사용자 지정 직렬화
'언어 자료구조 알고리즘 > Escort C#' 카테고리의 다른 글
[C#] 12. 직렬화와 리플렉션 - 리플렉션 (0) | 2016.05.16 |
---|---|
[C#] 12. 직렬화와 리플렉션 - 사용자 지정 직렬화 (0) | 2016.05.16 |
[C#] 12. 직렬화와 리플렉션 - 선별적 직렬화 (0) | 2016.05.16 |
[C#] 11. 예외 처리 - 파생 관계의 예외 잡기 (0) | 2016.05.16 |
[C#] 11. 예외 처리 - 예외 클래스 (0) | 2016.05.16 |
[C#] 11. 예외 처리 - 예외처리 구문 (0) | 2016.05.16 |
[C#] 10. .NET 어셈블리 - 모듈 작성 (0) | 2016.05.03 |
[C#] 10. .NET 어셈블리 - XML 문서 파일 (0) | 2016.05.03 |
[C#] 10. .NET 어셈블리 - 공용 어셈블리 (0) | 2016.05.03 |
[C#] 10. .NET 어셈블리 - 전용 어셈블리 (0) | 2016.05.03 |