상세 컨텐츠

본문 제목

객체 직렬화

.Net Framework/.Net Framework 2.0

by 탑~! 2008. 4. 18. 12:47

본문

※ 직렬화(Serialization)

 

1. 직렬화의 사전적인 의미

병행 수행되는 트랜잭션 집합의 수행 순서를 E라 할 때, E가 임의의 직렬 수행 순서인 S와 동일한 결과를 생성하는 경우의 S E에 대하여 일컫는 용어.

네이버 IT 용어사전

 

IT 용어사전의 정의는 대략 난감하지 않을 수 없다 --;

결국 직렬의 수행순서가 기존의 수행순서와 동일하면 이것을 기존 것의 직렬화라고 해석할 수 있겠다.

(같은 말인가 ^^;)

 

2. 보다 프로그램적인 접근

직렬화는 결국 컴퓨터상의 특정 데이터를 어딘가로 전달하기 좋도록 가공하는 과정을 뜻한다.

여기서 어딘가로란 것은 다른 프로세스, 네트워크 저 넘어, 시스템 저장소(파일, 메모리 등) 등을

말한다. 결국 어딘가로 는 특정 저장소로 통하는 스트림이라고 볼 수 있겠다.

닷넷 프레임워크에서 객체는 스트림으로 직렬화하고 스트림으로부터 역 직렬화 된다.

 

클래스의 인스턴스(객체)는 생성되면서 메모리에 올라가게 된다.

이것을 Live Object 라고 하는데 이 객체를 직렬화하여 스트림을 통해 특정 저장소로 저장시킬 수 있다. 이것을 Frozen Object Stream 이라고 한다.  그리고 난 후 Frozen Object Stream으로부터 역 직렬화를 통해 다시 원상태의 Live Object (객체)를 생성할 수 있다.

 

 

 

 

결론적으로 직렬화란 특정 개체를 읽고 쓰는 기능이라고 할 수 있다.

 

직렬화에서 기억해야 할 것은 다음과 같다.

- What: 무엇을 직렬화 할 것인가?

보통 객체나 구조체와 같이 특정 속성 집합이 대상이 된다.

         (물론 정수와 같은 단일 값도 직렬화 할 수 있다)

- Where: 어디로 저장할 것인가?

              스트림에 해당 한다. 보통 네트워크 통신에서의 소켓 또는 파일스트림 등이 목적지이다.

- How: 어떻게 직렬화 할 것인가?

             직렬화의 기본은 메모리상의 객체를 고정된 바이트 단위로 데이터를 저장하고 이를 스트림

             에 쓰도록 한다. 닷넷에서는 바이너리, XML, SOAP 3가지 직렬화 방식을 지원한다.

            

 

 

3. 직렬화 방식

 

3.1 바이너리 직렬화

객체를 프린트 불가능한 바이트 형 데이터(이진 형식)로 직렬화 한다.

이 직렬화 방식은 데이터의 타입정보가 포함되어 역 직렬화 시 원래의 객체와 똑 같은 객체로 만들 수 있다는 장점이 있다.

또한 직렬화된 크기가 매우 작다는 장점도 가진다., 이 방식은 호환성 문제를 고려해야 하는 상황이 발생할 수 있다는 것이 단점이 되겠다.

서로 다른 운영체제(OS)간의 직렬화된 데이터 전송은 바이트 순서나 특정 데이터 형의 크기 차이 등에 따른 호환성(이식성) 문제가 대두되기도 한다.

 

3.2 XML 직렬화

객체를 XML 문자열로 직렬화 한다.

이 방식은 데이터의 타입정보가 포함되지 않는 단점과 결과물의 크기가 매우 크질 수 있다는 단점이 있다.

, 이 방식은 바이너리 직렬화와는 반대로 상호운용성(이식성)이 매우 좋다.그럴 수 밖에 없는 것이 XML 많은 서비스에서 해석 가능한 표준화된 표기법이기 때문이다.

 

3.3 SOAP 직렬화

이 방식 역시 직렬화된 결과물은 XML 문자열이다.

SOAP XML 에 기반한 프로토콜이다.

그러나 XML은 데이터를 표현하기 위한 형식과 태그의 순서만을 정의할 뿐 데이터의 의미를 표현하는 방법에 대한 규약이 없다.

SOAP 는 데이터를 표현하기 위한 일반적인 요소에 대한 태그와 속성을 정의한 명세이다.

또한 이 방식은 닷넷 리모팅, 웹 서비스와 같은 SOAP 기반의 분산환경 통신 서비스와의 호환성을 가진다. 이 방식의  ,단점은 XML 직렬화와 유사하다.

 

결과물의 비교>>

다음은 동일한 객체에 대한 위 세가지 직렬화 방식의 결과물이다.

① 바이너리 직렬화

         
[1]   QConsoleApplication1, Version=1.0.2708.24734, Culture=neutral, PublicKeyToken=null   ConsoleApplication1.MyClass


  

myIntField

myDoubleField
myDecimalField 
 [1]   d         i@


300


참고> 위의 내용은 결과물을 단순히 복사/붙여넣기 한 내용인다.

      실제로 바이너리 직렬화의 결과물은 대부분 16진수의 데이터와 버전과 같은 일부 문자열이

      포함되어 있다.

 

XML 직렬화

<?xml version="1.0"?>

<MyClassxmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <myIntField>100</myIntField>

  <myDoubleField>200</myDoubleField>

  <myDecimalField>300</myDecimalField>

</MyClass>

 

SOAP 직렬화

<SOAP-ENV:Envelopexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0"SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<SOAP-ENV:Body>

<a1:MyClassid="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/ConsoleApplication1/ConsoleApplication1%2C%20Version%3D1.0.2708.24734%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">

<myIntField>100</myIntField>

<myDoubleField>200</myDoubleField>

<myDecimalField>300</myDecimalField>

</a1:MyClass>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

 

 

4. 포매터(Formatter)

닷넷에서는 바이너리, SOAP 직렬화를 위한 두 개의 포매터를 제공한다.

이 포매터를 이용하면 특정 객체를 스트림에 쓸 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

주의사항>>

포매터로 객체를 직렬화 하기 위해서는 직렬화 대상 클래스(또는 구조체)SerializableAttribute 특성이 적용되어야 한다.

 

그리고 XML 직렬화를 위한 XmlSerializer (System.Xml.Serialization.XmlSerializer)

제공한다.

 

4.1 XmlSerializer (XML 직렬화)

XML 직렬화는 바이너리 직렬화와는 다르게 직렬화 대상 데이터에 제약이 있다.

또한 XML 직렬화는 직렬화 대상 클래스에 SerializableAttribute 특성이 적용되지 않아도 된다.

 

XML 직렬화가 가능한 데이터 제약

-         클래스에 public으로 선언된 속성만 직렬화 가능

-         읽기/쓰기를 모두 가지는 프로퍼티

-         기본 생성자를 가진 클래스

-         DataSet 객체

-         ICollection IEnumerable를 구현한 클래스

-         XmlElement, XmlNode 객체

 

 

 

5. 실습

각각의 직렬화 방식을 사용해서 특정 객체의 직렬화/역 직렬화를 수행하는 데모를 살펴보자

 

5.1 직렬화 대상 클래스

[Serializable]

public class MyClass

{

        public int myIntField;       

        public double myDoubleField ;

        public decimal myDecimalField;

        //public int[] myIntArray;

 

        public MyClass()

        {

               this.myIntField = 100;

               this.myDoubleField = 200;

               this.myDecimalField = 300;

               //this.myIntArray = new int[1000];

        }

        public void MyMethod()

        {

               Console.WriteLine("Hello");

        }

}

 

5.2 직렬화 / 역 직렬화 하기

#region 직렬화

FileStream fileStream =

new FileStream("binary.bin",FileMode.Create,FileAccess.Write,FileShare.None);

FileStream fileStream2 =

new FileStream("soap.xml",FileMode.Create,FileAccess.Write,FileShare.None);

FileStream fileStream3 =

new FileStream("xml.xml",FileMode.Create,FileAccess.Write,FileShare.None);

 

MyClass myClass = new MyClass();                                           

                      

//1. 바이너리 직렬화

IFormatter binaryFormatter = new BinaryFormatter();

binaryFormatter.Serialize(fileStream,myClass);

 

//2. SOAP 직렬화

IFormatter soapFormatter = new SoapFormatter();

soapFormatter.Serialize(fileStream2,myClass);

 

//3. XML 직렬화

XmlSerializer xmlSerializer = new XmlSerializer(myClass.GetType());

xmlSerializer.Serialize(fileStream3,myClass);                                             

fileStream.Close();

fileStream2.Close();

fileStream3.Close();

#endregion

 

#region 역직렬화

//바이너리 역직렬화

FileStream fs =

new FileStream("binary.bin",FileMode.Open,FileAccess.Read,FileShare.None);                      

IFormatter bf = new BinaryFormatter();

object o = bf.Deserialize(fs);

MyClass mc = o as MyClass;

mc.MyMethod();               

 

//SOAP 역직렬화

FileStream fs2 =

new FileStream("soap.xml",FileMode.OpenOrCreate,FileAccess.Read,FileShare.None);

IFormatter sf = new SoapFormatter();                        

object o2 = sf.Deserialize(fs2);

MyClass mc2 = o2 as MyClass;

mc2.MyMethod();

 

//XML 역직렬화

FileStream fs3 =

new FileStream("xml.xml",FileMode.Open,FileAccess.Read,FileShare.None);                 

XmlSerializer xs = new XmlSerializer(typeof(MyClass));

object o3 = xs.Deserialize(fs3);

MyClass mc3 = o3 as MyClass;

mc3.MyMethod();              

              

fs.Close();

fs2.Close();

fs3.Close();

#endregion



출처 : http://www.mkex.pe.kr/

'.Net Framework > .Net Framework 2.0' 카테고리의 다른 글

DataSet SerializationFormat  (0) 2008.12.04
직렬화 제어  (0) 2008.04.18
직렬화 방법에 따른 크기 비교  (0) 2008.04.18
.NET의 Enterprise Service(COM+) 이해  (0) 2008.04.04
ClickOnce IIS Setup  (0) 2008.04.01

관련글 더보기