Post List

2018/01/08

C#__6.0 비트컨버터(BitConverter)

오늘 알아볼 BitConverter클래스는 업무 중 스프라이트 관련 툴을 C#으로 새롭게 제작하면서 공부하게 된 내용입니다.

저는 주로 데이터 입출력하는 과정에서 BitConverter를 사용하였으며, 파일 입출력관련해서는 FileStream을 사용하였습니다.

BitConverter클래스가 우선 무엇이냐면! C#에서 제공하는 클래스로 기본 데이터 형식을 바이트의 배열로, 바이트의 배열을 기본 데이터 형식으로 변환해주는 클래스랍니다.

주로 데이터 파일 관련해서 Read/Write할때 데이터값 변환에 주로 사용하였는데요. 이 때 FileStream으로 데이터파일을 읽을 때 byte배열로 읽어드릴 데이터의 크기만큼 할당 후 저장된 데이터를 읽어오는 수 밖에 없답니다.

그래서 배열에 데이터를 읽어온 후 배열에 담긴 데이터를 어떻게 기본 자료형으로 변환하는가! 입니다. 이때 바로 BitConverter를 통하여 쉽게 변환이 가능합답니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public virtual bool LoadFromFile(FileStream file)
{
       if (file == null)
           return false;
 
       byte[] spInfo                       = new byte[4];
       file.Read(spInfo, 04);
 
       width                               = BitConverter.ToUInt16(spInfo, 0);
       height                              = BitConverter.ToUInt16(spInfo, 2);
 
       ...
 
}
 
cs
위에 코드는 BitConverter를 어떻게 사용하였는지를 보여주는 Sample Code인데요, 저는 스프라이트 데이터를 읽어오기위해 처음 스프라이트의 가로 세로 사이즈를 읽어올려고 합니다.  

1
byte[] spInfo                       = new byte[4];
cs
데이터파일에 가로 세로값에 대한 데이터가 unsigned short 타입인 16bit 즉, 2byte의 크기로 각 저장되어있는데요, 2개의 ushort값을 읽어오기 위해 4byte의 배열의 크기를 할당했습니다.

1
file.Read(spInfo, 04);
cs
그리고 FileStream의 Read함수를 통해 할당한 배열에 데이터를 읽어옵니다. Read함수의 인자값으로는
첫번째 인자는 데이터를 저장할 바이트배열의 변수이며,
두번째 인자는 배열의 몇번째 인덱스 부터 데이터를 저장할지이며,
세번째 인자는 배열의 몇번째 인덱스 까지 데이터를 저장할지의 값을 전달합니다.

저는 가로 세로 데이터를 한번에 읽어오기 위해 0번 인덱스부터 4번 인덱스까지 총 4byte 데이터를 읽어 저장하도록 인자값을 넘겼습니다.

1
2
3
_width     = BitConverter.ToUInt16(spInfo, 0);
_height    = BitConverter.ToUInt16(spInfo, 2);
 
cs
이제 배열에 저장된 데이터를 ushort의 변수에 담아보겠습니다!
저는 가로와 세로 사이즈를 저장할 각 2byte의 변수로 변환을 해야하기 때문에 ToUInt16() 함수를 사용했습니다. 
 * 그 외에도 bool, char, double, int16, int32 등 다양한 데이터 크기에 따라 제공하는 함수가 있으니, 상황에 맞게 사용하시면 되겠습니다. 
여기서 첫번째 인자는 데이터를 가지고 있는 바이트 배열입니다.
두번째 인자는 첫번째 인자로 넘겨준 바이트 배열에서 데이터의 시작 인덱스를 넘겨주면 되겠습니다.
( 가로사이즈의 값은 0부터 1번 인덱스까지 2바이트에 저장이 되어있고, 세로사이즈는 2번부터 3번 인덱스까지 저장되어 있기 때문입니다 )


[ Byte -> Data Type ]
지금까지 바이트 배열에 담긴 데이터를 기본 데이터 타입으로 변환하는 방법을 알아보았습니다.
이번에는 반대로 기본 데이터 타입을 바이트 배열에 담는 방법을 알아보겠습니다!

  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public virtual bool SaveFromFile(FileStream file, ushort[] _lenbuffer = null)
{
      if (_lenbuffer == null)
          return false;
 
 
      byte[] _width                       = new byte[2];
      byte[] _height                      = new byte[2];
 
      _width                              = BitConverter.GetBytes(width);
      _height                             = BitConverter.GetBytes(height);
 
      file.Write(_width, 02);
      file.Write(_height, 02);
}
 
cs

아까 위에서 읽어들인 데이터를 다시 저장을 해보겠습니다.
스프라이트의 가로 세로 사이즈의 값을 저장하고 있는 ushort 타입 2개를 저장을 해볼껀데요,

여기서는 BitConverter GetBytes()함수를 통하여 ushort 데이터 타입에 저장된 값을 바이트 배열로 변환하겠습니다.

* 유의할 점은 바이트로 변환할 데이터 타입의 크기와 할당한 바이트 배열의 사이즈를 반드시 맞춰주셔야 합니다.

BitConverter클래스의 정의된 함수들을 살펴보시면 각 데이터 타입마다 GetBytes()함수들이 오버로딩되어있어 다양한 데이터 타입을 바이트 배열로 변환할 수 있답니다.

BitConverter 클래스의 더 자세한 내용은 MSDN을 참고하시면 되겠습니다. 감사합니다!