C# - 직렬화

김도현·2023년 10월 9일
0

TIL

목록 보기
45/76

직렬화이란?

직렬화(Serialization)는 클래스의 객체를 바이너리화 하는 것을 직렬화라고 합니다. 즉, 클래스 내부에 있는 데이터, 변수의 값들을 byte형식의 데이터로 만드는 것입니다.
이 직렬화는 예전에 사용했었지만 요즘에 객체 데이터를 JSON 형식으로 저장합니다.

그러나 JSON의 경우 pubilc 데이터를 String으로 변환하는 것이라 아무래도 한계가 있지만 직렬화의 경우에는 class의 상태 자체를 byte형식으로 변환하는 것이라 private과 상속을 받았으며 그 상위의 private 데이터까지 변환할 수 있습니다.
그러면 모든 것들을 직렬화를 하는 것이 좋을 것이라 생각하는데 직렬화에는 단점이 있다.

.NET에서 지원하는 기능

  1. NameSpace
    System.Runtime.Serialization
    System.Xml.Serialization
  2. 직렬화 메커니즘
    XmlSerializer
    DataContractSerializer
    BinaryFormatter

단점

  1. 메모리에 있는 내용을 그대로 byte 형식으로 변환시킨 것이라 메모장으로 열어 볼 때, json의 경우는 문법이 있기 때문에 이해를 할 수 있지만 직렬화 시킨 데이터는 이해할 수 없습니다.
    (반대로 데이터를 숨겨야할 필요가 있을때는 훌륭하다)

  2. 직렬화 시킨 데이터를 저장하고 혹시 소스가 변경되면(변수 명과 변수가 추가 등등) 그 전에 직렬화해 놓은 것을 다시 사용할 수 없습니다.

마지막으로 json의 형식은 언어와 관계없이 이식성이 있습니다만, 직렬화 데이터는 C#에서 만들었면 오로지 C#에서만 사용이 가능합니다.

정확히 말하자면 클래스가 변경되거나 다른 플랫폼에서 읽는게 전혀 불가능한 것이 아닙니다만, 데이터가 유실되거나 없어지는 문제가 발생합니다. 즉 버그 발생률이 생깁니다.

사용 방법

using System;
using System.IO;
// 직렬화를 위한 라이브러리
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApplication1
{
    [Serializable]
    class Node
    {
        private string data;
        public Node(string data)
        {
            this.data = data;
        }

        public void Print()
        {
            Console.WriteLine(this.data);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Node node = new Node("Test");

            // 직렬화 클래스
            var formatter = new BinaryFormatter();
            // 클래스를 직렬화하여 보관할 데이터
            byte[] data;
            using (MemoryStream stream = new MemoryStream())
            {
                formatter.Serialize(stream, node);
                data = new byte[stream.Length];
                //스트림을 byte[] 데이터로 변환한다.
                data = stream.GetBuffer();
            }

            using (MemoryStream stream = new MemoryStream())
            {
                // byte를 읽어드린다.
                stream.Write(data, 0, data.Length);
                // Stream seek을 맨 처음으로 돌린다.
                stream.Seek(0, SeekOrigin.Begin);
                // 클래스를 역직렬화 하고 Node클래스의 Print함수 실행.
                ((Node)formatter.Deserialize(stream)).Print();
            }

            // 직렬화 데이터를 파일로 저장한다.
            using (FileStream stream = new FileStream("f:\\C#\\Serializable.dat", FileMode.Create, FileAccess.Write))
            {
                formatter.Serialize(stream, node);
            }

            // 파일로 부터 직렬화 데이터를 읽어드린다.
            using (FileStream stream = new FileStream("f:\\C#\\Serializable.dat", FileMode.Open, FileAccess.Read))
            {
                // 클래스를 역직렬화 하고 Node클래스의 Print함수 실행.
                ((Node)formatter.Deserialize(stream)).Print();
            }

            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
    }
}

결과

Test
Test

참조사이트

명월일지
개발 일지

0개의 댓글