[C#] File 다루기 - 3. 인코딩(Encoding)과 디코딩(Decoding)
3. Text의 인코딩(Encoding)과 디코딩(Decoding)
컴퓨터에 저장된 문자열(Text)는 0과 1로 표시하는 bit단위로 저장되며 8bit와 같은 단위를 통해 대부분 문자 자체를 나타내거나 특정한 포맷을 표시하기도 합니다. 예를 들어 ASCII는 128개의 코드를 가지는데 .NET은 내부적으로 문자열을 인코딩하는데 Unicode라는 표준을 사용합니다. ASCII에 비해 Unicode는 훨씬 더 많은 코드를 가지고 있습니다.
때로는 문자열이 Unicode를 사용하지 않거나 Unicode를 변환시키기 위해 다른 곳으로 옮겨져야할 경우가 있는데 이 때문에 Encoding사이에서 어떻게 변화시킬 것인지를 아는 것은 매우 중요합니다.
아래는 문자열을 인코딩하는데 사용되는 다른 일반적인 방법을 나열한 것입니다.
ASCII | 매우 낮은 범위의 제한된 문자만을 Encoding할 수 있습니다. |
UTF-8 | 각 Unicode를 1~4바이트의 순서로 나타냅니다. 오늘날 가장 많이 사용되는 Encoding방식입니다. |
UTF-7 | UTF-8보다 7bit 시스템에서 더 높은 효휼성을 위해 디자인되었습니다. 그러나 보안과 안정성이슈가 있으므로 UTF-7대신 UTF-8사용을 권장합니다. |
UTF-16 | 각 Unicode를 한개 또는 2개의 16bit 정수의 순서로 나타냅니다. |
UTF-32 | 32-bit integer로 각 Unicode를 나타냅니다. 또한 가변길이의 Encoding을 수행하는 다른 Unicode Encoding과는 달리 고정길이의 Encoding을 수행합니다. |
ANSI/ISO | 특정 언어의 지원을 위한 다양한 Code Page를 위한 것입니다. |
● string을 byte array로 Encoding 하기
아래 예제는 짧은 문자열 값을 ASCII로 Encoding 하는 방법을 보여줍니다.
using System.Text;
Encoding encodingType = Encoding.ASCII;
string site = "cliél.com";
//UTF8로 site변수의 문자열 인코딩
byte[] encoded = encodingType.GetBytes(site);
Console.WriteLine($"{encodingType.GetType().Name} 인코딩({encoded.Length} bytes)");
//각 byte의 문자표시
foreach (byte b in encoded)
{
Console.WriteLine($"{(char)b}");
}
//UTF8로 문자열 디코딩
string decoded = encodingType.GetString(encoded);
Console.WriteLine(decoded);
// ASCIIEncodingSealed 인코딩(9 bytes)
// c
// l
// i
// ?
// l
// .
// c
// o
// m
// cli?l.com
예제를 실행하면 정확히 문자수만큼 9byte 크기로 Encoding 됨을 알 수 있는데 이때 ASCII에서는 é문자를 Encoding하지 못해 해당 결과가 ?문자로 대체되어 있음을 볼 수 있습니다.
이번에는 Encoding방식을 UTF8로 지정하여 다시 코드를 실행합니다.
Encoding encodingType = Encoding.UTF8;
...
// UTF8EncodingSealed 인코딩(10 bytes)
// c
// l
// i
// A
// ⓒ
// l
// .
// c
// o
// m
// cliel.com
결과를 보면 비록 é문자를 Encoding 하기 위해 2byte를 사용함으로써 최종 10 bytes의 크기로 늘어났지만 정상적으로 Encoding과 Decoding이 완료되었음을 확인할 수 있습니다.
● Text 파일의 Encoding과 Decoding
StreamReader나 StreamWriter와 같은 Stream Helper 클래스를 사용할 때 선택적으로 필요한 Encoding을 지정할 수 있습니다. 이를 위해 클래스의 생성자를 통해 두 번째 매개변수에 Encoding방식을 아래와 같이 지정합니다.
StreamReader reader = new(stream, Encoding.UTF8);
StreamWriter writer = new(stream, Encoding.UTF8);
가끔 다른 시스템에서 사용되는 경우 어떤 Encoding을 선택할지 알 수 없는 상황이라면 표현되어야 할 모든 문자를 표현하면서 가정적은 byte를 사용하는 Encoding방식을 선택해 보는 것이 좋습니다.