CSharp  Serialize

시리얼라이즈(직렬화)를 통해 객체를 다른 포맷의 정보로 임포트 익스포트 할수 있다.
데이터를 직렬화 하기 위해 Serialize,  원상태의 데이터로 만들기 위해 Deserialize 화 한다.

C++의 #pragma pack과 비슷한 기능이지만 더 다양하게 사용할수 있다.
다양한 포맷로 만들수 있다.

Binary Serialize

바이너리 직렬화는 오브젝트를 바이너리 포맷으로 Serialize 하고 오브젝트로 복구 할때는 다시 Deserialize 시킨다.

[Serializable] 속성을 사용해서 직렬화 하고 [NonSerialized] 속성을 사용해서 직렬화에서 제외 한다.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class Human
{
    private string _name;
    protected int _age;
    public int _gender;
 
    [NonSerialized]
    public float _speed;

    public Human(string name, int age, int gender)
    {
        _name = name;
        _age = age;
        _gender = gender;
    }

    public void Clear()
    {
        _name = "";
        _age = 0;
        _gender = 0;
    }
}


static void TestBinary()
{
    //파일 저장
    Human human = new Human("hebory", 30, 1);
    FileStream fs1 = new FileStream("human.bin", FileMode.Create, FileAccess.Write);
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(fs1, human);
    fs1.Close();


    //파일 로드
    human.Clear();
    FileStream fs2 = new FileStream("human.bin", FileMode.Open, FileAccess.Read);
    BinaryFormatter bf2 = new BinaryFormatter();
    human = (Human)bf2.Deserialize(fs2);
    fs2.Close();
}

바이너리 직렬화로 저장된 파일이다.



XML Serialize

XML 직렬화로 데이터를 XML,로 만들수 있다.
XML 직렬화는 [Serializable] , [NonSerialized] 속성이 적용 안되므로 필요 없다.
public 멤버 변수만 XML로 저장된다.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;

public class PublicHuman
{
    public string _name;
    public int _age;
    public int _gender;

    private float _speed;

    public PublicHuman(string name, int age, int gender)
    {
        _name = name;
        _age = age;
        _gender = gender;
    }

    public PublicHuman()
    {
        Clear();
    }

    public override string ToString()
    {
        return "이름: " + _name + "\n나이: " + _age + "\n성별: " + _gender + "\n";
    }

    public void Clear()
    {
        _name = "";
        _age = 0;
        _gender = 0;
    }

}


static void TestXml()
{
    // xml 형태로 파일 기록
    PublicHuman human = new PublicHuman("hebory", 30, 1);
    FileStream fs1 = new FileStream("human.xml", FileMode.Create, FileAccess.Write);
    XmlSerializer xs = new XmlSerializer(human.GetType());
    xs.Serialize(fs1, human);
    fs1.Close();

    // 파일 읽어오기
    human.Clear();
    FileStream fs2 = new FileStream("human.xml", FileMode.Open, FileAccess.Read);
    XmlSerializer xs2 = new XmlSerializer(human.GetType());
    human = (PublicHuman)xs2.Deserialize(fs2);
    fs2.Close();
    Console.Write(human.ToString());
}

XML 직렬화를 사용할때 주의 할점이 3가지가 있다.

1. 매개 변수가 없는 생성자를 만든다.

매개 변수 없는 생성자를 실행하면 다음 명령을 실행할때 에러가 발생한다.

XmlSerializer xs = new XmlSerializer(human.GetType());

매개 변수가 없는 생성자를 만들면 발생하지 않는다.

        public class PublicHuman
        {
            public string _name;

            [NonSerialized]
            public float _speed;

            public PublicHuman()
            {
            }
        }



2. 클래스는 public으로 선언한다.

클래스 접근 권도 public으로 선언해야 다음의 에러가 발생하지 않는다.

다음 명령을 실행할때 에러가 발생한다.

XmlSerializer xs = new XmlSerializer(human.GetType());

Program 클래스를 public으로 해야 에러가 발생하지 않는다.

public class Program




3. XML 파일

XML 직렬화에 의해 저장된 파일이다.

<?xml version="1.0"?>
<PublicHuman xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <_name>hebory</_name>
  <_age>30</_age>
  <_gender>1</_gender>
</PublicHuman>


소스 : serialize.cs

참조)
https://msdn.microsoft.com/ko-kr/library/ms233843.aspx
http://blog.naver.com/cra2yboy/90120861954
http://www.csharpstudy.com/Practical/Prac-Serialization.aspx