Perl / Windows / Unicode : Perl 을 통해 윈도우즈 유니코드 텍스트 저장하기
| 분류: Perl | 최초 작성: 2011-10-17 07:39:18 |
인코딩에 대한 문제는 꼭 CJK 가 아니더라도 어딜 가나 지옥구덩이인 모양이다. 이는 Perl 동네에서도 마찬가지인 듯 한데, 거기에 필자도 걸려들었다.
1. 유니코드에도 종류가 있다.
세계표준이라는 유니코드에도 온갖 종류가 있다. (자세한 내용은 참고문서 참조.) 그 중에서 윈도우즈에서 사용하고 있는 인코딩 방식은 UTF-16 LE 라고 하는 방식이다. (단, 윈도우즈 2000 이후의 윈도우즈를 의미함. 윈도우즈 98/SE 및 그 이전의 윈도우즈에서는 유니코드를 지원하지 않았다.) 윈도우즈에서 사용하는 표준 유니코드 형식으로 텍스트를 저장하기 위해서는 UTF-8을 UTF-16 LE 로 변환하는 작업을 거쳐야 한다.
참고로, 이 예제 소스의 모든 인코딩은 euc-kr(ansi) 였기 때문에, 초기에 문자열의 decode 를 euckr 인코딩으로 했다. 만약 사용자가 이 소스의 인코딩을 UTF-8로 저장하였다면 해당 부분은 utf8 로 설정하여야 한다.
use Encode;
my $TEXT = encode( "UTF-16LE", decode( "euckr", "This is the test of saving unicode text. 유니코드 텍스트 저장 테스트입니다." ) );
open my $fHandle, ">", "test.txt";
print $fHandle $TEXT;
close $fHandle;
2. 문제점 : Byte Order Mark (BOM)
그러나, 실제로 위의 코드를 실행한 후, 만들어진 test.txt 파일을 메모장으로 열어 보면 아마 난리가 나 있을 것이다. 구체적으로, 한글이 다 날아가 있고, 영문자들 사이사이에 한 칸씩 빈 칸이 보일 것이다. 에디트플러스 등의 프로그램으로 이 파일을 열려고 시도하면, 이 파일을 유니코드 텍스트 파일로 인식하지 못하고, 현재의 인코딩에서 깨진 문자가 나타날 수 있다는 등의 오류 메시지를 보여준다.
이것은, Perl 의 encode 모듈이 인코딩을 UTF-16LE 형식으로 변환하면서 필요한 Byte Order Mark[BOM]를 따로 넣어주지 않기 때문이다. 따라서 Perl 을 통해 유니코드(UTF-16LE) 텍스트 파일을 저장할 때에는 반드시 BOM을 함께 저장해 주어야 한다. 구체적으로, 다음과 같이 한다.
use Encode;
my $TEXT = decode( "euckr", "This is the test of saving unicode text. 유니코드 텍스트 저장 테스트입니다." );
open my $fHandle, ">:raw:encoding(UTF16-LE):crlf:utf8", "test.txt";
print $fHandle "\x{FEFF}"; # Little Endian 임을 표시해 준다.
print $fHandle $TEXT;
close $fHandle;
위와 같은 방법을 사용하여야만 윈도우즈에서 텍스트 파일로 읽을 때에 인코딩상 문제가 발생하지 않는다.
** 다만, 이와 같이 BOM이 마킹된 파일을 Perl 이 직접 핸들링할 때에는 몇몇 문제가 발생하는 것으로 알려져 있다. 특히 Perl 소스에 이런 BOM이 붙는 경우(UTF-8 인코딩을 사용하더라도 BOM이 붙을 수 있다.) 바로 오류가 발생하곤 하므로, 절대 소스 파일에는 BOM을 붙이지 않는다.
* 참고 페이지:
Writing a Unicode file via perl : http://blogs.msdn.com/b/brettsh/archive/2006/06/07/620986.aspx
유니코드의 종류 : http://mwultong.blogspot.com/2007/11/unicode.html (이게 다는 아닙니다. -필자 주)