Serialization - 객체 직렬화
객체를 연속적인 데이터를 변환하는것을 말합니다.
직렬화 객체를 저장하거나 메모리, 데이터베이스 또는 파일로 전송하기 위해 바이트 스트림으로 객체를 변환하는 프로세스이며, 주된 목적으로는 필요한 경우를 다시 가능하도록하기 위해 객체의 상태를 저장합니다. 반대의 과정을 역 직렬화(Deserialization)라고합니다.
System.Runtime.Serialization는 직렬화와 객체를 직렬화 복원에 필요한 클래스가 포함되어 있습니다.이 유형의 인스턴스가 직렬화 될 수 있다는 것을 나타 내기 위해 형식으로 SerializableAttribute 특성을 적용합니다.
만약 SerializableAttribute 특성이없는 경우 SerializationException 예외가 발생합니다.
클래스 내의 필드가 직렬화 가능하지 않은 경우, NonSerializedAttribute 특성을 적용 할 수 있습니다.
직렬화 유형의 필드가 포인터 핸들 또는 특정 환경에 고유 한 몇 가지 다른 데이터 구조를 포함하고,
필드를 의미 다른 환경에서 재구성 될 수없는 경우에는이 비 직렬화하도록 할 수있습니다.
직렬화 된 클래스는 SerializableAttribute로 표시되어 다른 클래스의 객체에 대한 참조를 포함하는 경우, 그 객체는 직렬화됩니다.
기본적인 객체 직렬화와 역직렬화
[Serializable]
public class MyObject
{
public int n1 = 0;
public int n2 = 0;
public String str = null;
}
static void Main(string[] args)
{
// 시리얼라이즈 (객체 직렬화)
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin",
FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
// 디시이얼라이즈 (역직렬화)
IFormatter readFormatter = new BinaryFormatter();
Stream readStream = new FileStream("MyFile.bin",
FileMode.Open,
FileAccess.Read,
FileShare.Read);
MyObject readObj = (MyObject)readFormatter.Deserialize(readStream);
readStream.Close();
Console.WriteLine("n1: {0}", readObj.n1);
Console.WriteLine("n2: {0}", readObj.n2);
Console.WriteLine("str: {0}", readObj.str);
}
//-- 결과
// -- MyFile.bin 파일 생성
// n1: 1
// n2: 24
// str: Some String
선택적 객체 직렬화
클래스 저장에게 멤버 변수 스레드 ID를 가질때 클래스가 직렬화되면, 스레드는 클래스가 더 이상 실행되지 않을 수 있습니다.
다음과 같이 NonSerialized 속성을 표시하여 직렬화되는 멤버 변수를 방지 할 수 있습니다.
[Serializable]
public class MyObject
{
public int n1;
[NonSerialized] public int n2;
public String str;
}
사용자 정의 직렬화
직렬화될 클래스의 ISerializable 인터페이스를 구현함으로써는 사용자 정의 직렬화를 할 수 있습니다.
[Serializable]
public class MyItemType : ISerializable
{
public MyItemType() { }
private string myProperty_value;
public string MyProperty
{
get { return myProperty_value; }
set { myProperty_value = value; }
}
// 해당 함수는 직렬화할때 호출됩니다.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("data", myProperty_value, typeof(string));
Console.WriteLine("직렬화 완료");
}
// 해당 생성자는 역직렬화일때 호출됩니다.
public MyItemType(SerializationInfo info, StreamingContext context)
{
myProperty_value = (string)info.GetValue("data", typeof(string));
myProperty_value = myProperty_value + " 확인";
Console.WriteLine("역직렬화 완료");
}
}
public static void SerializeItem(string fileName, IFormatter formatter)
{
MyItemType t = new MyItemType();
t.MyProperty = "Data";
FileStream s = new FileStream(fileName, FileMode.Create);
formatter.Serialize(s, t);
s.Close();
Console.WriteLine(t.MyProperty);
}
public static void DeserializeItem(string fileName, IFormatter formatter)
{
FileStream s = new FileStream(fileName, FileMode.Open);
MyItemType t = (MyItemType)formatter.Deserialize(s);
Console.WriteLine(t.MyProperty);
}
static void Main(string[] args)
{
string fileName = "MyFile.txt";
// 시리얼라이즈 (객체 직렬화)
MyItemType obj = new MyItemType();
IFormatter formatter = new BinaryFormatter();
SerializeItem(fileName, formatter);
// 디시이얼라이즈 (역직렬화)
DeserializeItem(fileName, formatter);
}
//-- 결과
// 직렬화 완료
// Data
// 역직렬화 완료
// Data 확인
[참고]
https://msdn.microsoft.com/en-us/library/ms973893.aspx
https://msdn.microsoft.com/ko-kr/library/system.runtime.serialization.serializationinfo(v=vs.110).aspx
'프로그래밍 > C#' 카테고리의 다른 글
[C#] 리플렉션 - Reflection (0) | 2022.06.22 |
---|---|
[C#] event 키워드 (0) | 2016.12.23 |
[C#] yield 키워드 (0) | 2016.10.29 |
[C#] where & Generics (형식 제약 조건) (0) | 2016.10.29 |
[C#] 무명 메서드(Anonymous Methods) (0) | 2016.09.29 |