Serialization & Deserialization(직렬화와 역직렬화)

Min·2024년 7월 13일
0

CPP

목록 보기
8/14
post-thumbnail

직렬화와 역직렬화

  • 직렬화란?
    데이터를 1Byte 단위로 쪼개서 버퍼에 적재하는 것

  • 역직렬화란?
    직렬화된 데이터를 원래 데이터로 복구하는 것
#include <iostream>
#include <vector>

int main()
{
	//데이터를 먼저 만들어보자
	int intData = 12345;
	//4바이트 2진수로 표현하면
	//00000000 00000000 00110000 00111001임
	//비트값으로 확인하면
	//00111001 00110000 00000000 00000000임
	//뒤부터 저장되는것을 알 수 있음
	//리틀엔디안 방식으로 데이터가 저장됨

	//Buffer는 데이터를 복사할 char 배열
	//어차피 int는 4byte니까 걍 char 4개짜리로 만들자
	std::vector<char> Buffer(4,0);

	//버퍼에 IntData를 복사하자
	memcpy_s(Buffer.data(), sizeof(intData), &intData, sizeof(intData));

	//결과를 보자
	//[57][48][0][0]가 저장됨 이게 Serialize의 가장 기본이라고 할 수있겠다.
	//즉 어떤 데이터를 바이트 단위 버퍼로 쪼개 관리하는것이 직렬화
	//비트값으로 확인하면
	//00111001 00110000 00000000 00000000

	//그럼 그럼 역직렬화는?
	//Buffer안에 데이터를 다시 int로 바꿔보자

	//데이터를 받을 놈
	int ReadData = 0;
	memcpy_s(&ReadData, sizeof(int), Buffer.data(), Buffer.size() * sizeof(char));
	
	//결과를 보자
	// *ReadData == 12345
	//알맞는 자료형에 알맞은 크기의 데이터를 복사하기만 하면, 해당 비트값을 해석하는건 자료형의 몫
	//잘 나옵니다


	//이번에는 스트링을 직렬화 해보자
	std::string StrData = "I am Hwang Seung-Min.";
	
	//string은 배열형이기 때문에 데이터의 크기가 정해져있는 자료형이 아니다
	//때문에 string의 길이를 알아야한다.
	//그래야 역직렬화를 할때, 길이에 맞춰 데이터를 담을 수 있다
	size_t StrDataLen = StrData.size();
	
	//그럼 두개의 데이터를 저장해야한다, 하나는 string의 길이, 다른 하나는 str데이터 그 자체
	//그만큼 이상의 버퍼 크기가 필요하겠죠? 대충 계산해서 넣읍시다
	Buffer.resize(sizeof(size_t) + StrDataLen * sizeof(char) + 1); // 맨뒤 \0를 생각하긴 했는데 흠...

	//버퍼에 StrDataLen값 먼저 복사하자
	memcpy_s(Buffer.data(), sizeof(size_t), &StrDataLen, sizeof(size_t));

	//StrData는 그 다음 위치부터 넣어야겠네요
	memcpy_s(Buffer.data() + sizeof(size_t), StrDataLen * sizeof(char), StrData.data(), StrDataLen * sizeof(char));

	//결과를 한번 봅시다
	//8바이트는 StrDataLen가, 그뒤 바이트들은 StrData로 잘 들어갔다.

	//이번엔다시 역직렬화
	std::string ReadStr;
	size_t ReadLen = 0;
	memcpy_s(&ReadLen, sizeof(size_t), Buffer.data(), sizeof(size_t));
	ReadStr.resize(ReadLen); //데이터를 읽어들일 메모리를 미리 확보
	memcpy_s(ReadStr.data(), ReadLen * sizeof(char), Buffer.data() + sizeof(ReadLen), ReadLen * sizeof(char));
	
	//결과를 보자
	//잘 나온다
	//데이터를 넣을 위치를 Offset으로 만들어 변수화하면 더 편하게 할 수 있다.
	//주소값이나 컴파일러 사양마다 자료형 크기가 달라질 수 있는 자료형들은 이런식의 직렬화가 사실 위험할 수 있다.
	//때문에 size_t를 직렬화 하는것도 안좋은습관 __int32 이런 자료형을 쓰는것이 안전할 수 있습니다.
}
profile
티내는 청년

0개의 댓글